Hai eseguito questa query di diagnostica temporale sul tuo server MySQL.
select @@time_zone, now(), utc_timestamp()
È chiaro dall'ora locale e dall'ora utc che l'impostazione del fuso orario di sistema della macchina del server è "Canada/Mountain" e il software del server MySQL non ha la propria impostazione del fuso orario.
Se prendi le tue tabelle e le sposti invariate su un server in un fuso orario vicino, puoi aggiornare il tuo software sempre per emettere il comando
set time_zone = 'Canada/Mountain';
subito dopo esserti connesso dal tuo software. Questo farà sì che la tua nuova connessione MySQL si comporti come quella attuale in base al fuso orario. Se possiedi il server MySQL puoi impostare il suo fuso orario predefinito secondo le indicazioni in questa pagina. http://dev.mysql.com/doc /refman/5.5/en/time-zone-support.html
Ora, ecco la storia dei tipi di dati temporali. DATE
, TIME
e DATETIME
sono tutti ignoranti il fuso orario . Dopo aver memorizzato un valore di data/ora, lo riacquisterai con lo stesso valore anche se modifichi le impostazioni del fuso orario.
Il TIMESTAMP
il tipo di dati è sensibile al fuso orario . Tali elementi di dati sono sempre archiviati in UTC, noto anche come Z, ora
, precedentemente noto come Greenwich Mean Time. Vengono sempre convertiti in UTC dopo essere stati archiviati e riconvertiti sempre dopo essere stati recuperati.
Le funzioni integrate
per ottenere la data e l'ora correnti (NOW()
e amici) sono sensibili al fuso orario . Daranno valori nell'ora locale. Le eccezioni sono le tre funzioni che iniziano con UTC_
che producono valori nell'ora UTC.
Molte applicazioni MySQL multi fuso orario utilizzano la seguente disciplina operativa:
- Chiedi a ciascun utente un fuso orario preferito dall'utente o scoprilo da qualche altro bit di dati personali sull'utente. (I telefoni hanno queste informazioni fornite in loro dalla rete.) Archivia come un zoneinfo-friendly descrittore del fuso orario ("America/New_York", "Canada/Mountain", "Europe/Vienna", ecc.) per conto dell'utente.
- Dopo aver stabilito una sessione MySQL per conto dell'utente, imposta il fuso orario dell'utente con un
set time_zone
query come quella mostrata sopra. Dovresti farlo subito dopo il tuoconnect
operazione. - Memorizza date e orari per gli utenti in
TIMESTAMP
tipi di dati. Verranno convertiti in UTC man mano che vengono archiviati. - Recuperali secondo necessità. Verranno riconvertiti all'ora locale.
L'idea è che il fuso orario dell'utente faccia parte del suo contesto. Funziona bene, perché se l'utente A è a Vancouver e l'utente B ad Halifax e per qualche motivo l'utente B visualizza i dati temporali dell'utente A, questi verranno mostrati a B nell'ora atlantica più o meno automaticamente.
È anche un bene perché si occupa in modo trasparente dei capricci globali del cambio dell'ora legale e dell'ora standard. Un timestamp della scorsa estate verrà visualizzato nell'ora locale della scorsa estate.
Molti gestori di server per uso globale impostano l'ora del server di sistema, o il fuso orario predefinito di MySQL, su UTC. (Il tuo no.)
Un altro modo per gestire tutto questo è il modo in cui hai iniziato. Scegli un fuso orario e memorizza i tuoi timestamp rispetto a quel fuso orario. È meglio se scegli un fuso orario che non alterna tra luce diurna e ora solare in quel caso. Quindi, quando si memorizzano i tempi nel database, convertire in modo esplicito. Memorizzeresti i tempi degli utenti a Ottawa facendo qualcosa del genere.
INSERT INTO tbl (appt) VALUES ( 'whatever-time' - INTERVAL 120 MINUTE)
e otterresti i valori allo stesso modo. Questo è soggetto a errori ma puoi farlo funzionare.
Infine, puoi eseguire tu stesso le conversioni. Se vuoi sapere quanti minuti di offset ci sono tra un fuso orario arbitrario e UTC, prova queste due query.
set time_zone = 'Canada/Atlantic';
select timestampdiff(minute, utc_timestamp(), now());
In questo periodo dell'anno restituisce -240, ovvero -4:00. È necessario utilizzare i minuti anziché le ore a causa della differenza di fuso orario di mezz'ora o quarto d'ora in alcuni paesi.
Infine, attenzione. TIMESTAMP
i tipi di dati non rappresentano i tempi prima del 1970. E, sulla mia istanza MariaDB 10.0, sembra andare all'inferno in un secchio subito dopo il 2038-01-19T03:14:07 UTC quando l'ora supera i 32 bit.