ProgrammazioneSviluppatore Backend, BI-analista

Spiega come gestire dati temporali e intervalli di date in SQL, quali sono le caratteristiche delle funzioni di lavoro con il tempo (DATEDIFF, DATEADD, INTERVAL) in diverse DBMS? Quali insidie possono presentarsi quando si lavora con i fusi orari? Fornisci un esempio di calcolo corretto della differenza di tempo.

Supera i colloqui con l'assistente IA Hintsage

Risposta

In SQL esiste un'ampia gamma di funzioni per lavorare con date e intervalli: DATEDIFF, DATEADD (T-SQL), gestione del tipo INTERVAL (PostgreSQL), funzionalità per la conversione degli orari in diversi fusi orari (AT TIME ZONE). Per lavorare correttamente con le date, è fondamentale utilizzare tipi di dati che tengano conto del fuso orario (TIMESTAMP WITH TIME ZONE, timestamptz), e non semplicemente DATE o DATETIME, specialmente per servizi globali.

Nei diversi DBMS, la sintassi e le caratteristiche di lavoro differiscono:

  • SQL Server: DATEDIFF, DATEADD, FORMAT, ma non c'è un vero INTERVAL. I fusi orari sono gestiti esplicitamente.
  • PostgreSQL: supporta INTERVAL, molte funzioni (+/- INTERVAL), gestione diretta dei fusi orari.

Gli errori si verificano spesso a causa della mancanza di coerenza tra la memorizzazione in UTC/orario locale e la mescolanza di operazioni che non tengono conto della differenza.

Esempio di calcolo della differenza (PostgreSQL)

SELECT EXTRACT(EPOCH FROM (event_end AT TIME ZONE 'UTC' - event_start AT TIME ZONE 'UTC')) / 3600 AS hours FROM events

Domanda insidiosa

Può la differenza di date in DATEDIFF dare un numero negativo, e che significa il loro ordine?

Risposta: Sì, DATEDIFF (DATEDIFF(day, d1, d2)) restituisce un numero negativo se d2 < d1. È importante non confondere l'ordine dei parametri: prima viene l'unità di misura, poi la data iniziale, quindi la data finale.

Esempio:

SELECT DATEDIFF(day, '2024-05-01', '2024-04-25') -- restituirà -6

Esempi di errori reali


Storia

In un progetto con utenti globali i report sono stati costruiti secondo l'orario locale dei server in ogni regione. Risultato — aggregazioni disallineate per data e comparsa di “buchi” al confine tra i giorni per gli utenti di altri fusi orari. Risolto convertendo tutti i dati temporali a UTC e ricalcolando solo per la visualizzazione.


Storia

Nel calcolo della durata di un abbonamento tramite DATEDIFF è stato confuso l'ordine delle date. Di conseguenza, alcuni utenti sono stati erroneamente classificati come “superutenti” con una durata evidente negativa. Risolto introducendo un controllo sull'ordine delle date.


Storia

Un sviluppatore ha memorizzato DATETIME senza tenere conto del fuso orario; durante la migrazione a PostgreSQL i valori sono stati interpretati come UTC, sebbene inizialmente fossero in GMT+3, il che ha portato a uno spostamento degli eventi nei report di 3 ore indietro. Conclusione — è sempre necessario memorizzare e convertire le date tenendo conto del fuso orario!