datetime - Manipolazione dei Valori di Data ed Orario
Scopo: Il modulo datetime include le funzioni e le classi per analizzare, formattare e compiere operazioni aritmetiche su date e orari.
Orari
I valori di orario sono rappresentati dalla classe time
. Una istanza di time
ha attributi per ora, minuto, secondo e microsecondo (rispettivamente hour
, minute
,second
e microsecond
). Può anche includere informazioni circa la zona di fuso orario.
# datetime_time.py
import datetime
t = datetime.time(1, 2, 3)
print(t)
print('ora :', t.hour)
print('minuto :', t.minute)
print('secondo :', t.second)
print('microsecondo:', t.microsecond)
print('zona fuso or:', t.tzinfo)
Gli argomenti per inizializzare una istanza di time
sono opzionali, ma il valore predefinito (0) è piuttosto improbabile che sia corretto.
$ python3 datetime_time.py 01:02:03 ora : 1 minuto : 2 secondo : 3 microsecondo: 0 zona fuso or: None
Una istanza di time
contiene solo valori di orario, non una data associata a un orario.
# datetime_time_minmax.py
import datetime
print('Orario min.:', datetime.time.min)
print('Orario max :', datetime.time.max)
print('Risoluzione:', datetime.time.resolution)
Gli attributi di classe min
e max
rappresentano i limiti validi di orario in un singolo giorno.
$ python3 datetime_time_minmax.py Orario min.: 00:00:00 Orario max : 23:59:59.999999 Risoluzione: 0:00:00.000001
La risoluzione per time
è limitata agli interi microsecondi.
# datetime_time_resolution.py
import datetime
for m in [1, 0, 0.1, 0.6]:
try:
print('{:02.1f} :'.format(m),
datetime.time(0, 0, 0, microsecond=m))
except TypeError as err:
print('ERRORE:', err)
Valori in virgola mobile per i microsecondi provocano un TypeError
.
$ python3 datetime_time_resolution.py 1.0 : 00:00:00.000001 0.0 : 00:00:00 ERRORE: integer argument expected, got float ERRORE: integer argument expected, got float
Date
I valori per date di calendario sono rappresentati con la classe date
. Le istanze hanno attributi per anno (year
), mese (month
) e giorno (day
). Con il metodo di classe today()
è semplice creare un oggetto data che rappresenta la data corrente.
# datetime_date.py
import datetime
today = datetime.date.today()
print(today)
print('ctime :', today.ctime())
tt = today.timetuple()
print('tupla : tm_year =', tt.tm_year)
print(' tm_mon =', tt.tm_mon)
print(' tm_mday =', tt.tm_mday)
print(' tm_hour =', tt.tm_hour)
print(' tm_min =', tt.tm_min)
print(' tm_sec =', tt.tm_sec)
print(' tm_wday =', tt.tm_wday)
print(' tm_yday =', tt.tm_yday)
print(' tm_isdst =', tt.tm_isdst)
print('ordinale:', today.toordinal())
print('Anno :', today.year)
print('Mese :', today.month)
print('Giorno :', today.day)
Questo esempio stampa la data corrente di diversi formati:
$ python3 datetime_date.py 2016-06-12 ctime : Sun Jun 12 00:00:00 2016 tupla : tm_year = 2016 tm_mon = 6 tm_mday = 12 tm_hour = 0 tm_min = 0 tm_sec = 0 tm_wday = 6 tm_yday = 164 tm_isdst = -1 ordinale: 736127 Anno : 2016 Mese : 6 Giorno : 12
Ci sono anche metodi di classe per creare istanze da marche temporali POSIX (fromtimestamp()
) o da interi che rappresentano valori di data dal calendario Gregoriano, dove il primo gennaio dell'anno 1 vale 1 e ogni giorno seguente incrementa il valore di 1 (fromordinal()
).
# datetime_date_fromordinal.py
import datetime
import time
o = 733114
print('o :', o)
print('fromordinal(o) :', datetime.date.fromordinal(o))
t = time.time()
print('t :', t)
print('fromtimestamp(t):', datetime.date.fromtimestamp(t))
Questo esempio illustra i diversi tipi di valore utilizzati da fromordinal()
e da fromtimestamp()
.
$ python3 datetime_date_fromordinal.py o : 733114 fromordinal(o) : 2008-03-13 t : 1465745266.076346 fromtimestamp(t): 2016-06-12
Così come per time
l'intervallo di valori data supportati può essere determinato utilizzando gli attributi min
e max
.
# datetime_date_minmax.py
import datetime
print('Minimo :', datetime.date.min)
print('Massimo :', datetime.date.max)
print('Risoluzione:', datetime.date.resolution)
import datetime
La risoluzione per le date è il giorno intero.
$ python3 datetime_date_minmax.py Minimo : 0001-01-01 Massimo : 9999-12-31 Risoluzione: 1 day, 0:00:00
Un altro modo per creare nuove istanze di date
è tramite il metodo replace()
di una istanza di date
esistente.
# datetime_date_replace.py
import datetime
d1 = datetime.date(2008, 3, 29)
print('d1:', d1.ctime())
d2 = d1.replace(year=2009)
print('d2:', d2.ctime())
Questo esempio modifica l'anno, lasciando mese e giorno invariati.
$ python3 datetime_date_replace.py d1: Sat Mar 29 00:00:00 2008 d2: Sun Mar 29 00:00:00 2009
Intervalli Temporali (timedelta)
Date future e passate possono essere calcolate utilizzando operazioni aritmetiche su due oggetti datetime, oppure combinando un datetime con un timedelta
. La sottrazione di date produce un timedelta
; e un timedelta
può essere aggiunto o sottratto da una data per produrne un'altra. I valori interi di timedelta
sono conservati in giorni, secondi e microsecondi.
# datetime_timedelta.py
import datetime
print("microsecondi:", datetime.timedelta(microseconds=1))
print("millisecondi:", datetime.timedelta(milliseconds=1))
print("secondi :", datetime.timedelta(seconds=1))
print("minuti :", datetime.timedelta(minutes=1))
print("ore :", datetime.timedelta(hours=1))
print("giorni :", datetime.timedelta(days=1))
print("settimane :", datetime.timedelta(weeks=1))
Valori di livello intermedio passati al costruttore sono convertiti in giorni, secondi e microsecondi.
$ python3 datetime_timedelta.py microsecondi: 0:00:00.000001 millisecondi: 0:00:00.001000 secondi : 0:00:01 minuti : 0:01:00 ore : 1:00:00 giorni : 1 day, 0:00:00 settimane : 7 days, 0:00:00
La durata completa di un intervallo temporale può essere recuperato come numero di secondi tramite total_seconds()
.
# datetime_timedelta_total_seconds.py
import datetime
for delta in [datetime.timedelta(microseconds=1),
datetime.timedelta(milliseconds=1),
datetime.timedelta(seconds=1),
datetime.timedelta(minutes=1),
datetime.timedelta(hours=1),
datetime.timedelta(days=1),
datetime.timedelta(weeks=1),
]:
print('{:15} = {:8} secondi'.format(
str(delta), delta.total_seconds())
)
Il valore di ritorno è un numero a virgola mobile (float
), per gestire durate inferiori al secondo.
$ python3 datetime_timedelta_total_seconds.py 0:00:00.000001 = 1e-06 secondi 0:00:00.001000 = 0.001 secondi 0:00:01 = 1.0 secondi 0:01:00 = 60.0 secondi 1:00:00 = 3600.0 secondi 1 day, 0:00:00 = 86400.0 secondi 7 days, 0:00:00 = 604800.0 secondi
Aritmetica sulle Date
Per compiere operazioni matematiche sulle date si utilizzano gli operatori aritmetici standard.
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
import datetime
today = datetime.date.today()
print('Oggi :', today)
one_day = datetime.timedelta(days=1)
print('Un giorno:', one_day)
yesterday = today - one_day
print('Ieri :', yesterday)
tomorrow = today + one_day
print('Domani :', tomorrow)
print('domani - ieri:', tomorrow - yesterday)
print('ieri - domani:', yesterday - tomorrow)
Questo esempio con oggetti date
illustra l'uso di oggetti timedelta
per calcolare nuove date, e per sottrarre istanze di date
per produrre timedelta
(incluso un intervallo temporale negativo).
$ python3 datetime_date_math.py Oggi : 2016-06-12 Un giorno: 1 day, 0:00:00 Ieri : 2016-06-11 Domani : 2016-06-13 domani - ieri: 2 days, 0:00:00 ieri - domani: -2 days, 0:00:00
Un oggetto timedelta
supporta anche operazioni aritmetiche con interi, valori a virgola mobile e altre istanze di timedelta
.
# datetime_timedelta_math.py
import datetime
one_day = datetime.timedelta(days=1)
print('1 giorno :', one_day)
print('5 giorni :', one_day * 5)
print('1.5 giorni :', one_day * 1.5)
print('1/4 giorno :', one_day / 4)
# si assume un ora per il pranzo
work_day = datetime.timedelta(hours=7)
meeting_length = datetime.timedelta(hours=1)
print('riunioni al giorno :', work_day / meeting_length)
In questo esempio, sono calcolati diversi multipli per un singolo giorno, e i risultanti timedelta
contengono il numero di giorni od ore appropriato. L'esempio finale dimostra come calcolare valori combinando due oggetti timedelta
. In questo caso il risultato è un numero a virgola mobile.
$ python3 datetime_timedelta_math.py 1 giorno : 1 day, 0:00:00 5 giorni : 5 days, 0:00:00 1.5 giorni : 1 day, 12:00:00 1/4 giorno : 6:00:00 riunioni al giorno : 7.0
Confrontare Valori
I valori sia di data che di orario possono essere confrontati tramite gli operatori di confronto standard per determinare quale è il più o il meno recente.
# datetime_comparing.py
import datetime
import time
print('Orari:')
t1 = datetime.time(12, 55, 0)
print(' t1:', t1)
t2 = datetime.time(13, 5, 0)
print(' t2:', t2)
print(' t1 < t2:', t1 < t2)
print
print('Date :')
d1 = datetime.date.today()
print(' d1:', d1)
d2 = datetime.date.today() + datetime.timedelta(days=1)
print(' d2:', d2)
print(' d1 > d2:', d1 > d2)
Tutti gli operatori di confronto sono supportati.
$ python3 datetime_comparing.py Orari: t1: 12:55:00 t2: 13:05:00 t1 < t2: True Date : d1: 2016-06-19 d2: 2016-06-20 d1 > d2: False
Combinare Date ed Orari
Si utilizza la classe datetime
per conservare valori sia di data che di orario. Così come per date
ci sono parecchi metodi di classe di convenienza per la creazione di istanze di datetime
derivate da altri valori comuni.
# datetime_datetime.py
import datetime
print('Oggi ,', datetime.datetime.today())
print('UTC adesso,', datetime.datetime.utcnow())
print
FIELDS = [
('year', 'anno'),
('month', 'mese'),
('day', 'giorno'),
('hour', 'ora'),
('minute', 'minuto'),
('second', 'secondi'),
('microsecond', 'microsecondi')
]
d = datetime.datetime.now()
for attr, descr in FIELDS:
print('{:15}, {}'.format(descr, getattr(d, attr)))
Come ci si potrebbe aspettare, l'istanza di datetime
ha tutti gli attributi degli oggetti date
e time
.
$ python3 datetime_datetime.py Oggi , 2016-06-18 16:31:57.334704 UTC adesso, 2016-06-18 14:31:57.334757 anno , 2016 mese , 6 giorno , 18 ora , 16 minuto , 31 secondi , 57 microsecondi , 334779
Proprio come con date
, datetime
fornisce dei metodi di classe di convenienza per la creazione di nuove istanze. Include anche fromordinal()
e fromtimestamp()
.
# datetime_datetime_combine.py
import datetime
t = datetime.time(1, 2, 3)
print('t :', t)
d = datetime.date.today()
print('d :', d)
dt = datetime.datetime.combine(d, t)
print('dt:', dt)
combine()
crea istanze di datetime
da una istanza di date
e una di time
.
$ python3 datetime_datetime_combine.py t : 01:02:03 d : 2016-06-18 dt: 2016-06-18 01:02:03
Formattazione ed Elaborazione
La rappresentazione stringa predefinita di un oggetto datetime
utilizza il formato ISO-8601 (YYYY-MM-DDTHH:MM:SS.mmmmmm). Formati alternativi possono essere generati utilizzando strftime()
.
# datetime_datetime_strptime.py
import datetime
format = "%a %b %d %H:%M:%S %Y"
today = datetime.datetime.today()
print('ISO :', today)
s = today.strftime(format)
print('strftime:', s)
d = datetime.datetime.strptime(s, format)
print('strptime:', d.strftime(format))
Si usa datetime.strptime()
per convertire stringhe formattate in istanze di datetime
.
$ python3 datetime_datetime_strptime.py ISO : 2016-06-18 16:49:00.075603 strftime: Sat Jun 18 16:49:00 2016 strptime: Sat Jun 18 16:49:00 2016
Gli stessi codici di formattazione possono essere utilizzati con il mini linguaggio di formattazione stringhe di Python piazzandoli dopo il :
nella specifica del campo della stringa di formato.
# datetime_format.py
import datetime
today = datetime.datetime.today()
print('ISO :', today)
print('format(): {:%a %b %d %H:%M:%S %Y}'.format(today))
Ciascun codice di formato di datetime
deve essere preceduto da %
e tutti i successivi :
sono trattati come caratteri letterali da includere nell'output.
$ python3 datetime_format.py ISO : 2016-06-18 16:52:39.249801 format(): Sat Jun 18 16:52:39 2016
La tabella seguente mostra tutti i codici di formattazione per le ore 15.00 del pomeriggio del 5 giugno 2016 con la localizzazione italiana.
SIMBOLO | SIGNIFICATO | ESEMPIO |
---|---|---|
%a | Giorno della settimana abbreviato | 'dom' |
%A | Nome del giorno della settimana | 'domenica' |
%w | Numero del giorno della settimana - da 0 (Domenica) a 6 (Sabato) | '0' |
%d | Giorno del mese (con zero iniziali) | '05' |
%b | Nome del mese abbreviato | 'giu' |
%B | Nome del mese completo | 'giugno' |
%m | Mese nell'anno | '06' |
%y | Anno senza cifre del secolo | '16' |
%Y | Anno completo | '2016' |
%H | Ora su 24 | '15' |
%I | Ora su 12 | '03' |
%p | AM/PM | '' |
%M | Minuti | '00' |
%S | Secondi | '00' |
%f | Microsecondi | '000000' |
%z | scostamento UTC per oggetti che tengono conto della zone di fuso orario | '' |
%Z | Nome della zona di fuso orario | '' |
%j | Numero giorno nell'anno | '157' |
%W | Numero settimana nell'anno | '22' |
%c | Rappresentazione di data e ora per la localizzazione corrente | '05/06/2015 15:00:00' |
%x | Rappresentazione di data per la localizzazione corrente | '05/06/16' |
%X | Rappresentazione di ora per la localizzazione corrente | '15:00:00' |
%% | Il carattere letterale % | '%' |
Zone di Fuso Orario
All'interno di datetime, le zone di fuso orario sono rappresentate da sottoclassi di tzinfo
. Visto che tzinfo
è una classe base astratta, le applicazioni devono definire una sottoclasse e fornire le implementazioni appropriate per alcuni metodi affinchè siano utilizzabili.
datetime include una implementazione, poco sofisticata se vogliamo, nella classe timezone
che utilizza uno scostamento fisso rispetto all'UTC e non supporta valori di scostamento diversi per diversi giorni dell'anno, a esempio laddove viene applicata l'ora legale, oppure laddove lo scostamento dall'UTC sia mutato nel tempo.
# datetime_timezone.py
import datetime
min6 = datetime.timezone(datetime.timedelta(hours=-6))
plus6 = datetime.timezone(datetime.timedelta(hours=6))
d = datetime.datetime.now(min6)
print(min6, ':', d)
print(datetime.timezone.utc, ':',
d.astimezone(datetime.timezone.utc))
print(plus6, ':', d.astimezone(plus6))
# conversione alla zona di fuso orario corrente del sistema
d_system = d.astimezone()
print(d_system.tzinfo, ' :', d_system)
https://it.wikipedia.org/wiki/Tempo_coordinato_universale https://it.wikipedia.org/wiki/Tempo_coordinato_universale Per convertire un valore datetime
da una zona di fuso orario all'altra si utilizzi astimezone()
. Nell'esempio qui sopra sono mostrate due zone di fuso orario separate da 6 ore dalle parti opposte rispetto all'UTC, viene inoltre utilizzata l'istanza utc
da datetime.timezone
come riferimento. L'output finale mostra il valore nella zona di fuso orario del sistema, acquisita dalla chiamata di astimezone()
senza argomenti.
$ python3 datetime_timezone.py UTC-06:00 : 2016-06-19 02:05:43.105264-06:00 UTC+00:00 : 2016-06-19 08:05:43.105264+00:00 UTC+06:00 : 2016-06-19 14:05:43.105264+06:00
Vedere anche:
- datetime
- La documentazione della libreria standard per questo modulo.
- Note di portabilità
- Note di portabilità per datetime
- calendar
- Il modulo
calendar
- dateutil
-
dateutil
da Labix estende il modulodatetime
con funzionalità aggiuntive - pytz
- Database delle zone di fuso orario nel mondo e classi per rendere gli oggetti
datetime
consapevoli delle zone di fuso orario - Wikipedia: Calendario Gregoriano prolettico
- Una descrizione dei sistema di calendario Gregoriano
- ISO 8601
- La rappresentazione numerica standard di date e orari