4. Ora locale
4.1. Tempo Coordinato Universale (UTC)
Poiché le regole dell'ora legale per i fusi orari locali sono così complicate e possono cambiare in base alla legge locale in momenti imprevedibili, la vera interoperabilità si ottiene meglio utilizzando il Tempo Coordinato Universale (UTC). Questa specifica non tiene conto delle regole dei fusi orari locali.
Perché usare l'UTC?
- ✅ Standard temporale unificato globalmente
- ✅ Non influenzato dall'ora legale
- ✅ Non influenzato da decisioni politiche
- ✅ Garantisce l'interoperabilità
4.2. Offset locali
L'offset tra l'ora locale e l'UTC è spesso un'informazione utile. Ad esempio, nella posta elettronica (RFC2822, [IMAIL-UPDATE]), l'offset locale fornisce un'euristica utile per determinare la probabilità di una risposta tempestiva. I tentativi di etichettare gli offset locali con stringhe alfabetiche hanno portato a una scarsa interoperabilità in passato [IMAIL], [HOST-REQ]. Di conseguenza, RFC2822 [IMAIL-UPDATE] ha reso obbligatori gli offset numerici.
Calcolo dell'offset numerico
Gli offset numerici sono calcolati come «ora locale meno UTC». Quindi l'ora equivalente in UTC può essere determinata sottraendo l'offset dall'ora locale.
Esempio 1:
Ora locale: 18:50:00-04:00
Ora UTC: 18:50:00 - (-04:00) = 18:50:00 + 04:00 = 22:50:00Z
Verifica: Eastern Daylight Time (EDT) è UTC-4
Esempio 2:
Ora locale: 15:30:00+08:00
Ora UTC: 15:30:00 - (+08:00) = 15:30:00 - 08:00 = 07:30:00Z
Verifica: China Standard Time (CST) è UTC+8
Note importanti
Nota: Seguendo ISO 8601, gli offset numerici rappresentano solo fusi orari che differiscono dall'UTC per un numero intero di minuti. Tuttavia, molti fusi orari storici differiscono dall'UTC per un numero non intero di minuti. Per rappresentare esattamente tali timestamp storici, le applicazioni devono (MUST) convertirli in un fuso orario rappresentabile.
Esempi di fusi orari storici:
Alcuni orari locali alla fine del XIX secolo:
- Amsterdam: UTC+00:19:32
- Parigi: UTC+00:09:21
Questi non possono essere rappresentati con precisione in RFC 3339 e devono essere arrotondati al minuto più vicino
4.3. Convenzione per offset locale sconosciuto
Se l'ora in UTC è nota, ma l'offset rispetto all'ora locale è sconosciuto, questo può essere rappresentato con un offset di "-00:00". Questo differisce semanticamente da un offset di "Z" o "+00:00", che implica che l'UTC è il punto di riferimento preferito per l'ora specificata. RFC2822 [IMAIL-UPDATE] descrive una convenzione simile per la posta elettronica.
Distinzione tra tre rappresentazioni
Z o +00:00:
2002-07-15T10:30:00Z
2002-07-15T10:30:00+00:00
Significato: Questo orario È l'ora UTC, l'UTC è il punto di riferimento preferito
-00:00:
2002-07-15T10:30:00-00:00
Significato: L'ora UTC è 10:30:00, ma l'offset del fuso orario locale è sconosciuto
(possibilmente da un sistema che non conosce l'impostazione del fuso orario)
Scenari di utilizzo:
Scenario 1: Log del server, noto per essere UTC → usare Z
Scenario 2: Timestamp generato da dispositivo, il dispositivo è in UTC ma non conosce il fuso locale → usare -00:00
Scenario 3: Esplicitamente a Londra (GMT) → usare +00:00
4.4. Ora locale non qualificata
Un certo numero di dispositivi attualmente connessi a Internet eseguono i loro orologi interni in ora locale e non sono a conoscenza dell'UTC. Sebbene Internet abbia una tradizione di accettare la realtà nella progettazione delle specifiche, questo non dovrebbe essere fatto a scapito dell'interoperabilità. Poiché l'interpretazione di un fuso orario locale non qualificato fallirà in circa 23/24 del globo,
Requisiti obbligatori
I protocolli Internet devono (MUST) generare timestamp completamente qualificati.
Ciò significa che i protocolli Internet non devono (MUST NOT) utilizzare l'ora locale senza informazioni sul fuso orario.
Esempi errati:
❌ 2002-07-15T10:30:00 (nessuna informazione sul fuso orario)
Esempi corretti:
✅ 2002-07-15T10:30:00Z (UTC)
✅ 2002-07-15T10:30:00+08:00 (fuso orario esplicito)
✅ 2002-07-15T10:30:00-00:00 (UTC ma zona sconosciuta)
Problemi di interoperabilità
Se viene utilizzata un'ora locale non qualificata:
Mittente: 2002-07-15T10:30:00 (ora locale di New York, in realtà UTC-4)
Destinatario a Tokyo: Interpreta come ora di Tokyo (UTC+9)
Errore di differenza oraria: 13 ore!
Raccomandazioni per l'implementazione
Progettazione del sistema
# Raccomandato: Memorizzare sempre l'ora in UTC
def store_timestamp():
utc_time = datetime.now(timezone.utc)
return utc_time.isoformat() # 2024-12-21T10:30:00+00:00
# Quando si visualizza: Convertire nel fuso orario locale dell'utente
def display_timestamp(utc_time, user_timezone):
local_time = utc_time.astimezone(user_timezone)
return local_time.isoformat()
Archiviazione nel database
-- Raccomandato: Utilizzare TIMESTAMP WITH TIME ZONE
CREATE TABLE events (
id SERIAL,
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);
-- Evitare: TIMESTAMP WITHOUT TIME ZONE (causa ambiguità)
Principio chiave: Memorizzare internamente in UTC, convertire nel fuso orario locale quando si visualizza. Non utilizzare mai timestamp senza informazioni sul fuso orario per lo scambio di dati.