Comprendere il Modulo Datetime di Python
Impara a lavorare con date e ore in Python usando il modulo datetime: date, time, datetime, timedelta, strftime, strptime e fusi orari.
Python non dispone di un tipo di dato built-in dedicato alle date. Il modulo datetime della libreria standard fornisce invece un toolkit completo per creare, manipolare, formattare e analizzare date e orari. Questo capitolo tratta tutte le classi principali — date, time, datetime, timedelta e timezone — e mostra i pattern pratici che userai regolarmente.
Importare il Modulo
Il modulo datetime fa parte della libreria standard e non richiede alcuna installazione. Puoi importarlo in due modi comuni:
# Import the module and qualify every name
import datetime
today = datetime.date.today()
# Import specific classes directly
from datetime import date, time, datetime, timedelta, timezone
today = date.today()Lo stile from datetime import ... è più conciso in pratica ed è utilizzato in tutto questo capitolo.
La Classe date
date rappresenta una data del calendario (anno, mese, giorno) senza componente oraria.
Creare Oggetti date
Accedere agli Attributi di date
Una volta che si dispone di un oggetto date, è possibile leggerne l'anno, il mese e il giorno come attributi interi, e verificare in quale giorno della settimana cade:
from datetime import date
d = date(2024, 6, 15)
print(d.year) # 2024
print(d.month) # 6
print(d.day) # 15
# weekday(): Monday = 0, Sunday = 6
print(d.weekday()) # 5 (Saturday)
# isoweekday(): Monday = 1, Sunday = 7
print(d.isoweekday()) # 6 (Saturday)La Classe time
time rappresenta un orario del giorno (ora, minuto, secondo, microsecondo) indipendentemente da una data specifica.
from datetime import time
# time(hour, minute, second) — all arguments optional, default to 0
t = time(14, 30, 0)
print(t) # 14:30:00
print(t.hour) # 14
print(t.minute) # 30
print(t.second) # 0La classe time è più utile quando è necessario memorizzare o confrontare orari senza preoccuparsi della data, ad esempio "ricordami alle 09:00 ogni giorno."
La Classe datetime
datetime è la classe principale. Combina una data completa e un orario del giorno in un unico oggetto ed è quella che userai nella maggior parte dei programmi reali.
Ottenere la Data e l'Ora Correnti
from datetime import datetime
# Local system time (naive — no time zone)
now = datetime.now()
print(now) # e.g. 2024-06-15 14:30:45.123456
# UTC time
utc_now = datetime.utcnow()
print(utc_now) # e.g. 2024-06-15 18:30:45.123456Creare Oggetti datetime
from datetime import datetime, date, time
# Constructor: datetime(year, month, day, hour=0, minute=0, second=0)
dt = datetime(2024, 6, 15, 14, 30, 45)
print(dt) # 2024-06-15 14:30:45
# From an ISO 8601 string
dt2 = datetime.fromisoformat("2024-06-15T14:30:45")
print(dt2) # 2024-06-15 14:30:45
# Combine a date and a time object
combined = datetime.combine(date(2024, 6, 15), time(14, 30, 0))
print(combined) # 2024-06-15 14:30:00Accedere agli Attributi di datetime
datetime espone tutti gli attributi sia di date che di time:
from datetime import datetime
dt = datetime(2024, 6, 15, 14, 30, 45)
print(dt.year) # 2024
print(dt.month) # 6
print(dt.day) # 15
print(dt.hour) # 14
print(dt.minute) # 30
print(dt.second) # 45
# Extract just the date or time part
print(dt.date()) # 2024-06-15
print(dt.time()) # 14:30:45La Classe timedelta
timedelta rappresenta una durata — la differenza tra due istanti nel tempo. Si usa per aggiungere o sottrarre intervalli di tempo agli oggetti date e datetime.
Creare e Usare timedelta
from datetime import date, timedelta
today = date(2024, 6, 15)
# Add 30 days
future = today + timedelta(days=30)
print(future) # 2024-07-15
# Subtract 7 days
last_week = today - timedelta(weeks=1)
print(last_week) # 2024-06-08
# timedelta can express days, seconds, and microseconds
# Convenience arguments: days, seconds, microseconds, milliseconds, minutes, hours, weeks
delta = timedelta(hours=2, minutes=30)
print(delta) # 2:30:00Calcolare la Differenza tra Due Date
Sottrarre un oggetto date o datetime da un altro restituisce un timedelta:
from datetime import date
start = date(2024, 1, 1)
end = date(2024, 6, 15)
diff = end - start
print(diff) # 166 days, 0:00:00
print(diff.days) # 166Questo è il modo standard per calcolare quanti giorni intercorrono tra due date. Usa .total_seconds() su un timedelta se hai bisogno dell'intervallo in secondi.
Formattare Date e Orari (strftime)
strftime ("string format time") converte un oggetto date o datetime in una stringa leggibile dall'uomo. Si passa una stringa di formato che contiene direttive che iniziano con %.
from datetime import datetime
dt = datetime(2024, 6, 15, 14, 30, 45)
print(dt.strftime("%Y-%m-%d")) # 2024-06-15
print(dt.strftime("%d/%m/%Y")) # 15/06/2024
print(dt.strftime("%A, %B %d, %Y")) # Saturday, June 15, 2024
print(dt.strftime("%I:%M %p")) # 02:30 PM
print(dt.strftime("%Y-%m-%d %H:%M:%S")) # 2024-06-15 14:30:45Direttive Comuni di strftime
| Direttiva | Significato | Esempio |
|---|---|---|
%Y | Anno a 4 cifre | 2024 |
%y | Anno a 2 cifre | 24 |
%m | Mese come numero con zero iniziale | 06 |
%B | Nome completo del mese | June |
%b | Nome abbreviato del mese | Jun |
%d | Giorno del mese con zero iniziale | 15 |
%A | Nome completo del giorno della settimana | Saturday |
%a | Nome abbreviato del giorno della settimana | Sat |
%H | Ora (orologio 24 ore) | 14 |
%I | Ora (orologio 12 ore) | 02 |
%M | Minuto | 30 |
%S | Secondo | 45 |
%p | AM o PM | PM |
%j | Giorno dell'anno | 167 |
%W | Numero della settimana dell'anno | 24 |
Analizzare Date e Orari (strptime)
strptime ("string parse time") è l'operazione inversa di strftime: converte una stringa in un oggetto datetime. È necessario fornire una stringa di formato che corrisponda all'input.
Un errore comune: strptime restituisce sempre un datetime, anche quando la stringa contiene solo una data. Chiama .date() sul risultato se hai bisogno di un semplice oggetto date.
Formato ISO 8601
Lo standard ISO 8601 (YYYY-MM-DDTHH:MM:SS) è il modo più portabile per scambiare valori di data e ora. Python dispone di strumenti built-in per gestirlo:
from datetime import datetime
dt = datetime(2024, 6, 15, 14, 30, 45)
# Produce ISO 8601 string
print(dt.isoformat()) # 2024-06-15T14:30:45
# Parse ISO 8601 string (Python 3.7+)
dt2 = datetime.fromisoformat("2024-06-15T14:30:45")
print(dt2) # 2024-06-15 14:30:45Lavorare con i Timestamp
Un timestamp Unix è il numero di secondi trascorsi dal 1° gennaio 1970 00:00:00 UTC. Python può convertire tra timestamp e oggetti datetime:
Fusi Orari
Per impostazione predefinita, datetime.now() restituisce un datetime naive — non contiene informazioni sul fuso orario. Allegando un oggetto tzinfo lo si rende aware. I datetime aware sono indispensabili quando il programma gestisce utenti in più fusi orari o memorizza timestamp in un database.
Usare il timezone Built-in
datetime.timezone fornisce timezone.utc e consente di creare zone con offset fisso:
from datetime import datetime, timezone, timedelta
# Create an aware UTC datetime
utc_dt = datetime(2024, 6, 15, 14, 30, 45, tzinfo=timezone.utc)
print(utc_dt) # 2024-06-15 14:30:45+00:00
# Create a fixed +5:30 (India Standard Time) offset
ist_offset = timezone(timedelta(hours=5, minutes=30))
ist_dt = utc_dt.astimezone(ist_offset)
print(ist_dt) # 2024-06-15 20:00:45+05:30Usare zoneinfo (Python 3.9+)
Per i fusi orari IANA reali come America/New_York o Asia/Tokyo, usa il modulo built-in zoneinfo (Python 3.9+). Gestisce automaticamente l'ora legale.
from datetime import datetime, timezone
from zoneinfo import ZoneInfo
# UTC aware datetime
utc_dt = datetime(2024, 6, 15, 14, 30, 45, tzinfo=timezone.utc)
# Convert to Eastern Time (handles DST automatically)
eastern = ZoneInfo("America/New_York")
eastern_dt = utc_dt.astimezone(eastern)
print(eastern_dt) # 2024-06-15 10:30:45-04:00
# Convert to Tokyo time
tokyo = ZoneInfo("Asia/Tokyo")
tokyo_dt = utc_dt.astimezone(tokyo)
print(tokyo_dt) # 2024-06-15 23:30:45+09:00Su Python 3.8 e versioni precedenti, installa la libreria di terze parti pytz per il supporto alle zone IANA.
Sostituire Componenti
replace() restituisce un nuovo oggetto con campi specifici modificati. L'originale non viene mai mutato.
from datetime import datetime
dt = datetime(2024, 6, 15, 14, 30, 45)
# Change only the year
dt2 = dt.replace(year=2025)
print(dt2) # 2025-06-15 14:30:45
# Change hour and minute
dt3 = dt.replace(hour=9, minute=0, second=0)
print(dt3) # 2024-06-15 09:00:00Confrontare Date e Orari
Gli oggetti date e datetime supportano tutti gli operatori di confronto standard:
from datetime import date
d1 = date(2024, 1, 1)
d2 = date(2024, 6, 15)
print(d1 < d2) # True
print(d1 == d2) # False
# Find the earliest date
earliest = min(d1, d2)
print(earliest) # 2024-01-01Confronta solo datetime aware con datetime aware e naive con naive — mescolarli genera un TypeError.
Mettere Tutto Insieme
Ecco un esempio pratico che combina diversi concetti: calcola quanti giorni mancano a una scadenza futura e formatta entrambe le date per la visualizzazione.
from datetime import date
deadline = date(2024, 12, 31)
today = date(2024, 6, 15)
days_left = (deadline - today).days
print(f"Today: {today.strftime('%B %d, %Y')}") # June 15, 2024
print(f"Deadline: {deadline.strftime('%B %d, %Y')}") # December 31, 2024
print(f"Days remaining: {days_left}") # 199Riferimento Rapido
| Operazione | Codice |
|---|---|
| Data odierna | date.today() |
| Data e ora correnti | datetime.now() |
| Data specifica | date(2024, 6, 15) |
| Data da stringa | datetime.strptime(s, fmt) |
| Data in stringa | dt.strftime(fmt) |
| Formato ISO | dt.isoformat() / datetime.fromisoformat(s) |
| Aggiungere/sottrarre giorni | d + timedelta(days=N) |
| Giorni tra due date | (d2 - d1).days |
| Convertire il fuso orario | dt.astimezone(ZoneInfo("Zone/Name")) |