Mysql
 sql >> Database >  >> RDS >> Mysql

Campi data/ora MySQL e ora legale:come faccio a fare riferimento all'ora extra?

L'ho capito per i miei scopi. Riassumerò quello che ho imparato (scusate, queste note sono prolisse; servono tanto per il mio futuro rinvio quanto qualsiasi altra cosa).

Contrariamente a quanto ho detto in uno dei miei commenti precedenti, i campi DATETIME e TIMESTAMP do comportarsi diversamente. I campi TIMESTAMP (come indicano i documenti) prendono tutto ciò che li invii nel formato "AAAA-MM-GG hh:mm:ss" e lo convertono dal tuo fuso orario corrente all'ora UTC. Il contrario avviene in modo trasparente ogni volta che si recuperano i dati. I campi DATETIME non effettuano questa conversione. Prendono tutto ciò che gli invii e lo archiviano direttamente.

Né i tipi di campo DATETIME né TIMESTAMP possono memorizzare accuratamente i dati in un fuso orario che osserva l'ora legale . Se memorizzi "2009-11-01 01:30:00" i campi non hanno modo di distinguere quale versione di 1:30 volevi -- la versione -04:00 o -05:00.

Ok, quindi dobbiamo archiviare i nostri dati in un fuso orario diverso dall'ora legale (come UTC). I campi TIMESTAMP non sono in grado di gestire questi dati in modo accurato per motivi che spiegherò:se il tuo sistema è impostato su un fuso orario DST, ciò che inserisci in TIMESTAMP potrebbe non essere quello che torni indietro. Anche se gli invii dati che hai già convertito in UTC, assumerà comunque che i dati siano nel tuo fuso orario locale ed eseguirà un'altra conversione in UTC. Questo viaggio di andata e ritorno da locale a UTC applicato da TIMESTAMP va in perdita quando il tuo fuso orario locale osserva l'ora legale (dal "2009-11-01 01:30:00" mappa a 2 diversi orari possibili).

Con DATETIME puoi archiviare i tuoi dati in qualsiasi fuso orario desideri e avere la certezza di ricevere indietro qualunque cosa lo invii (non vieni costretto alle conversioni di andata e ritorno con perdite che i campi TIMESTAMP ti impongono). Quindi la soluzione è utilizzare un campo DATETIME e prima di salvare nel campo converti dal fuso orario del tuo sistema in qualsiasi fuso orario non DST in cui desideri salvarlo (penso che UTC sia probabilmente l'opzione migliore). Ciò ti consente di creare la logica di conversione nel tuo linguaggio di scripting in modo da poter salvare esplicitamente l'equivalente UTC di "2009-11-01 01:30:00 -04:00" o ""2009-11-01 01:30:00 -05:00".

Un'altra cosa importante da notare è che le funzioni matematiche data/ora di MySQL non funzionano correttamente attorno ai limiti dell'ora legale se si memorizzano le date in una TZ DST. Quindi un motivo in più per risparmiare in UTC.

In poche parole ora faccio questo:

Quando si recuperano i dati dal database:

Interpreta in modo esplicito i dati dal database come UTC al di fuori di MySQL per ottenere un timestamp Unix accurato. Uso la funzione strtotime() di PHP o la sua classe DateTime per questo. Non può essere eseguito in modo affidabile all'interno di MySQL utilizzando le funzioni CONVERT_TZ() o UNIX_TIMESTAMP() di MySQL perché CONVERT_TZ produrrà solo un valore "AAAA-MM-GG hh:mm:ss" che soffre di problemi di ambiguità e UNIX_TIMESTAMP() ne presume l'input è nel fuso orario del sistema, non nel fuso orario in cui i dati sono stati effettivamente archiviati (UTC).

Quando si archiviano i dati nel database:

Converti la tua data nell'ora UTC precisa che desideri al di fuori di MySQL. Ad esempio:con la classe DateTime di PHP puoi specificare "2009-11-01 1:30:00 EST" distintamente da "2009-11-01 1:30:00 EDT", quindi convertirlo in UTC e salvare l'ora UTC corretta nel tuo campo DATETIME.

Uff. Grazie mille per il contributo e l'aiuto di tutti. Speriamo che questo risparmi a qualcun altro qualche mal di testa lungo la strada.

A proposito, lo vedo su MySQL 5.0.22 e 5.0.27