Scopo | Il modulo calendar implementa le classi per lavorare con le date per gestire valori orientati ad anno/mese/settimana |
Versione Python | 1.4, con aggionamenti in 2.5 |
A partire dal 1 gennaio 2021 le versioni 2.x di Python non sono piu' supportate. Ti invito a consultare la corrispondente versione 3.x dell'articolo per il modulo calendar
Il modulo calendar definisce la classe Calendar, che incapsula i calcoli per valori tipo le date delle settimane in certo mese od anno. Inoltre, le classi TextCalendar e HTMLCalendar possono produrre un output preformattato.
Un esempio molto semplice, che produce un output con testo formattato per questo mese con TextCalendar, usa il metodo prmonth()
import calendar
c = calendar.TextCalendar(calendar.SUNDAY)
c.prmonth(2007, 7)
E' stato detto a TextCalendar di iniziare le settimane dalla domenica, secondo la convenzione americana. Il comportamento predefinito è di iniziare con il lunedì, secondo la convenzione europea.
L'output risulta così:
$ python calendar_textcalendar.py July 2007 Su Mo Tu We Th Fr Sa 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
L'output HTML per lo stesso periodo di tempo è leggermente diverso, visto che non c'è un metodo prmonth().
import calendar
c = calendar.HTMLCalendar(calendar.SUNDAY)
print c.formatmonth(2007, 7)
L'output interpretato sembra pressochè il medesimo, ma incapsulato nei tag HTML. Si può anche notare che ogni cella della tabella ha un attributo di classe che corrisponde al giorno della settimana.
$ python calendar_htmlcalendar.py <table border="0" cellpadding="0" cellspacing="0" class="month"> <tr><th colspan="7" class="month">July 2007</th></tr> <tr><th class="sun">Sun</th><th class="mon">Mon</th><th class="tue">Tue</th><th class="wed">Wed</th><th class="thu">Thu</th><th class="fri">Fri</th><th class="sat">Sat</th></tr> <tr><td class="sun">1</td><td class="mon">2</td><td class="tue">3</td><td class="wed">4</td><td class="thu">5</td><td class="fri">6</td><td class="sat">7</td></tr> <tr><td class="sun">8</td><td class="mon">9</td><td class="tue">10</td><td class="wed">11</td><td class="thu">12</td><td class="fri">13</td><td class="sat">14</td></tr> <tr><td class="sun">15</td><td class="mon">16</td><td class="tue">17</td><td class="wed">18</td><td class="thu">19</td><td class="fri">20</td><td class="sat">21</td></tr> <tr><td class="sun">22</td><td class="mon">23</td><td class="tue">24</td><td class="wed">25</td><td class="thu">26</td><td class="fri">27</td><td class="sat">28</td></tr> <tr><td class="sun">29</td><td class="mon">30</td><td class="tue">31</td><td class="noday"> </td><td class="noday"> </td><td class="noday"> </td><td class="noday"> </td></tr> </table>
Se serve produrre un output in un formato diverso da quelli predefiniti, si può usare calendar per calcolare le date ed organizzare i valori in intervalli di settimane e mesi, e successivamente iterare con i valori autonomamente. I metodi weekheader(), monthcalendar() e yeardays2calendar() sono particolarmente utili per questo tipo di lavoro.
La chiamata di
yeardays2calendar()
fornisce una sequenza di liste di "righe di mesi". Ogni lista comprende i mesi come un'altra lista di settimane. Le settimane sono rappresentate in liste di tuple composte dal numero del giorno del mese (1-31) e dal numero della settimana (0-6). I giorni che si trovano al di fuori del mese hanno un il numero 0.
import calendar
import pprint
pprint.pprint(calendar.Calendar(calendar.SUNDAY).yeardays2calendar(2007, 2))
Chiamando yeardays2calendar(2007,2) si ottengono i dati per il 2007, disposti su due mesi per riga.
$ python calendar_yeardays2calendar.py [[[[(0, 6), (1, 0), (2, 1), (3, 2), (4, 3), (5, 4), (6, 5)], [(7, 6), (8, 0), (9, 1), (10, 2), (11, 3), (12, 4), (13, 5)], [(14, 6), (15, 0), (16, 1), (17, 2), (18, 3), (19, 4), (20, 5)], [(21, 6), (22, 0), (23, 1), (24, 2), (25, 3), (26, 4), (27, 5)], [(28, 6), (29, 0), (30, 1), (31, 2), (0, 3), (0, 4), (0, 5)]], [[(0, 6), (0, 0), (0, 1), (0, 2), (1, 3), (2, 4), (3, 5)], [(4, 6), (5, 0), (6, 1), (7, 2), (8, 3), (9, 4), (10, 5)], [(11, 6), (12, 0), (13, 1), (14, 2), (15, 3), (16, 4), (17, 5)], [(18, 6), (19, 0), (20, 1), (21, 2), (22, 3), (23, 4), (24, 5)], [(25, 6), (26, 0), (27, 1), (28, 2), (0, 3), (0, 4), (0, 5)]]], [[[(0, 6), (0, 0), (0, 1), (0, 2), (1, 3), (2, 4), (3, 5)], [(4, 6), (5, 0), (6, 1), (7, 2), (8, 3), (9, 4), (10, 5)], [(11, 6), (12, 0), (13, 1), (14, 2), (15, 3), (16, 4), (17, 5)], [(18, 6), (19, 0), (20, 1), (21, 2), (22, 3), (23, 4), (24, 5)], [(25, 6), (26, 0), (27, 1), (28, 2), (29, 3), (30, 4), (31, 5)]], [[(1, 6), (2, 0), (3, 1), (4, 2), (5, 3), (6, 4), (7, 5)], [(8, 6), (9, 0), (10, 1), (11, 2), (12, 3), (13, 4), (14, 5)], [(15, 6), (16, 0), (17, 1), (18, 2), (19, 3), (20, 4), (21, 5)], [(22, 6), (23, 0), (24, 1), (25, 2), (26, 3), (27, 4), (28, 5)], [(29, 6), (30, 0), (0, 1), (0, 2), (0, 3), (0, 4), (0, 5)]]], [[[(0, 6), (0, 0), (1, 1), (2, 2), (3, 3), (4, 4), (5, 5)], [(6, 6), (7, 0), (8, 1), (9, 2), (10, 3), (11, 4), (12, 5)], [(13, 6), (14, 0), (15, 1), (16, 2), (17, 3), (18, 4), (19, 5)], [(20, 6), (21, 0), (22, 1), (23, 2), (24, 3), (25, 4), (26, 5)], [(27, 6), (28, 0), (29, 1), (30, 2), (31, 3), (0, 4), (0, 5)]], [[(0, 6), (0, 0), (0, 1), (0, 2), (0, 3), (1, 4), (2, 5)], [(3, 6), (4, 0), (5, 1), (6, 2), (7, 3), (8, 4), (9, 5)], [(10, 6), (11, 0), (12, 1), (13, 2), (14, 3), (15, 4), (16, 5)], [(17, 6), (18, 0), (19, 1), (20, 2), (21, 3), (22, 4), (23, 5)], [(24, 6), (25, 0), (26, 1), (27, 2), (28, 3), (29, 4), (30, 5)]]], [[[(1, 6), (2, 0), (3, 1), (4, 2), (5, 3), (6, 4), (7, 5)], [(8, 6), (9, 0), (10, 1), (11, 2), (12, 3), (13, 4), (14, 5)], [(15, 6), (16, 0), (17, 1), (18, 2), (19, 3), (20, 4), (21, 5)], [(22, 6), (23, 0), (24, 1), (25, 2), (26, 3), (27, 4), (28, 5)], [(29, 6), (30, 0), (31, 1), (0, 2), (0, 3), (0, 4), (0, 5)]], [[(0, 6), (0, 0), (0, 1), (1, 2), (2, 3), (3, 4), (4, 5)], [(5, 6), (6, 0), (7, 1), (8, 2), (9, 3), (10, 4), (11, 5)], [(12, 6), (13, 0), (14, 1), (15, 2), (16, 3), (17, 4), (18, 5)], [(19, 6), (20, 0), (21, 1), (22, 2), (23, 3), (24, 4), (25, 5)], [(26, 6), (27, 0), (28, 1), (29, 2), (30, 3), (31, 4), (0, 5)]]], [[[(0, 6), (0, 0), (0, 1), (0, 2), (0, 3), (0, 4), (1, 5)], [(2, 6), (3, 0), (4, 1), (5, 2), (6, 3), (7, 4), (8, 5)], [(9, 6), (10, 0), (11, 1), (12, 2), (13, 3), (14, 4), (15, 5)], [(16, 6), (17, 0), (18, 1), (19, 2), (20, 3), (21, 4), (22, 5)], [(23, 6), (24, 0), (25, 1), (26, 2), (27, 3), (28, 4), (29, 5)], [(30, 6), (0, 0), (0, 1), (0, 2), (0, 3), (0, 4), (0, 5)]], [[(0, 6), (1, 0), (2, 1), (3, 2), (4, 3), (5, 4), (6, 5)], [(7, 6), (8, 0), (9, 1), (10, 2), (11, 3), (12, 4), (13, 5)], [(14, 6), (15, 0), (16, 1), (17, 2), (18, 3), (19, 4), (20, 5)], [(21, 6), (22, 0), (23, 1), (24, 2), (25, 3), (26, 4), (27, 5)], [(28, 6), (29, 0), (30, 1), (31, 2), (0, 3), (0, 4), (0, 5)]]], [[[(0, 6), (0, 0), (0, 1), (0, 2), (1, 3), (2, 4), (3, 5)], [(4, 6), (5, 0), (6, 1), (7, 2), (8, 3), (9, 4), (10, 5)], [(11, 6), (12, 0), (13, 1), (14, 2), (15, 3), (16, 4), (17, 5)], [(18, 6), (19, 0), (20, 1), (21, 2), (22, 3), (23, 4), (24, 5)], [(25, 6), (26, 0), (27, 1), (28, 2), (29, 3), (30, 4), (0, 5)]], [[(0, 6), (0, 0), (0, 1), (0, 2), (0, 3), (0, 4), (1, 5)], [(2, 6), (3, 0), (4, 1), (5, 2), (6, 3), (7, 4), (8, 5)], [(9, 6), (10, 0), (11, 1), (12, 2), (13, 3), (14, 4), (15, 5)], [(16, 6), (17, 0), (18, 1), (19, 2), (20, 3), (21, 4), (22, 5)], [(23, 6), (24, 0), (25, 1), (26, 2), (27, 3), (28, 4), (29, 5)], [(30, 6), (31, 0), (0, 1), (0, 2), (0, 3), (0, 4), (0, 5)]]]]
Questo è l'equivalente dei dati usati da formatyear()
import calendar
print calendar.TextCalendar(calendar.SUNDAY).formatyear(2007, 2, 1, 1, 2)
che con gli stessi parametri produce un output tipo:
$ python calendar_formatyear.py 2007 January February Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa 1 2 3 4 5 6 1 2 3 7 8 9 10 11 12 13 4 5 6 7 8 9 10 14 15 16 17 18 19 20 11 12 13 14 15 16 17 21 22 23 24 25 26 27 18 19 20 21 22 23 24 28 29 30 31 25 26 27 28 March April Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa 1 2 3 1 2 3 4 5 6 7 4 5 6 7 8 9 10 8 9 10 11 12 13 14 11 12 13 14 15 16 17 15 16 17 18 19 20 21 18 19 20 21 22 23 24 22 23 24 25 26 27 28 25 26 27 28 29 30 31 29 30 May June Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa 1 2 3 4 5 1 2 6 7 8 9 10 11 12 3 4 5 6 7 8 9 13 14 15 16 17 18 19 10 11 12 13 14 15 16 20 21 22 23 24 25 26 17 18 19 20 21 22 23 27 28 29 30 31 24 25 26 27 28 29 30 July August Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa 1 2 3 4 5 6 7 1 2 3 4 8 9 10 11 12 13 14 5 6 7 8 9 10 11 15 16 17 18 19 20 21 12 13 14 15 16 17 18 22 23 24 25 26 27 28 19 20 21 22 23 24 25 29 30 31 26 27 28 29 30 31 September October Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa 1 1 2 3 4 5 6 2 3 4 5 6 7 8 7 8 9 10 11 12 13 9 10 11 12 13 14 15 14 15 16 17 18 19 20 16 17 18 19 20 21 22 21 22 23 24 25 26 27 23 24 25 26 27 28 29 28 29 30 31 30 November December Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa 1 2 3 1 4 5 6 7 8 9 10 2 3 4 5 6 7 8 11 12 13 14 15 16 17 9 10 11 12 13 14 15 18 19 20 21 22 23 24 16 17 18 19 20 21 22 25 26 27 28 29 30 23 24 25 26 27 28 29 30 31
Se per una qualche ragione si vuole formattare da soli l'output (ad esempio per includere collegamenti nell'output HTML), verranno utili gli attributi del modulo day_name, day_abbr, month_name e month_abbr. Essi sono automaticamente configurati secondo la localizzazione corrente.
Sebbene il modulo calendar si focalizzi principalmente sulla stampa di calendari completi in vari formati, fornisce anche delle funzioni utili per lavorare con le date in altri modi, tipo calcolare le date per un evento ricorrente. Ad esempio, il Python Atlanta User's Group si incontra il secondo giovedì di ogni mese. Per calcolare le date degli incontri per un anno, si potrebbe utilizzare il valore restituito da monthcalendar()
import calendar
import pprint
pprint.pprint(calendar.monthcalendar(2007, 7))
Notare che alcuni giorni hanno valore 0. Questi sono i giorni della settimana che si sovrappongono al mese considerato, ma che fanno parte di un altro mese.
$ python calendar_monthcalendar.py [[0, 0, 0, 0, 0, 0, 1], [2, 3, 4, 5, 6, 7, 8], [9, 10, 11, 12, 13, 14, 15], [16, 17, 18, 19, 20, 21, 22], [23, 24, 25, 26, 27, 28, 29], [30, 31, 0, 0, 0, 0, 0]]
Ricordare che, come valore predefinito, il primo giorno del mese è lunedì. E' possibile cambiarlo chiamando
setfirstweekday()
. D'altro canto, visto che il modulo calendar include delle costanti per indicizzare gli intervalli di date restituite da
monthcalendar()
, è molto più conveniente saltare quel passo in questo caso.
Per calcolare le date per gli incontri del PyATL per il 2007, sapendo che deve essere il secondo giovedì di ogni mese, possiamo usare i valori 0 per sapere se il giovedì della prima settimana è incluso nel mese (o se il mese inizia, ad esempio, il venerdì)
import calendar
# Mostra ogni mese
for month in range(1, 13):
# Calcola le date di ogni settimana che si sovrappongono nel mese
c = calendar.monthcalendar(2007, month)
first_week = c[0]
second_week = c[1]
third_week = c[2]
# Se c'è un giovedi' nella prima settimana, il secondo giovedi'
# è nella seconda settimana. Altrimenti il secondo giovedi'
# deve essere nella terza settimana.
if first_week[calendar.THURSDAY]:
meeting_date = second_week[calendar.THURSDAY]
else:
meeting_date = third_week[calendar.THURSDAY]
print '%3s: %2s' % (month, meeting_date)
Quindi il calendario degli incontri del PyATL per il 2007 è:
$ python calendar_secondthursday.py 1: 11 2: 8 3: 8 4: 12 5: 10 6: 14 7: 12 8: 9 9: 13 10: 11 11: 8 12: 13