Ho affrontato questa situazione in modo estensivo in un'applicazione PHP/MySQL che ho scritto per un operatore di jet privato poco più di un anno fa. Esistono diverse strategie per gestire i fusi orari in queste due piattaforme, ma spiegherò come l'ho fatto. Imposta il server MySQL su UTC ed eseguo ogni script PHP nel fuso orario specificato dall'utente durante la procedura di registrazione per il profilo utente.
MySQL e PHP (PHP 5.2 e versioni successive) hanno entrambi datetime nativi. Il datetime di MySQL è un tipo di dati primitivo, mentre il PHP 5.2 e versioni successive offre il built-in DateTime class. Il datatype di MySQL datetime non include i metadati per il fuso orario, ma un oggetto DateTime di PHP include sempre un fuso orario. Se il costruttore PHP datetime non specifica il fuso orario facoltativo nel secondo argomento, il costruttore PHP datetime utilizza la variabile di ambiente php.
Sia MySQL che PHP hanno il fuso orario predefinito impostato nei file di configurazione. MySQL utilizza datetime set in the config file per ciascuna connessione db, a meno che l'utente non specifichi un fuso orario diverso dopo l'avvio della connessione con il comando SET time_zone = [timezone];
. PHP imposta anche una variabile di ambiente timezone per ogni script utilizzando il fuso orario impostato nel file di configurazione del server e questa variabile d'ambiente può essere sostituita utilizzando la funzione PHP date_default_timezone_set()
dopo l'avvio dello script.
La classe DateTime di PHP ha una proprietà denominata fuso orario, che è un PHP DateTimeZone object. L'oggetto DateTimeZone viene specificato utilizzando una stringa per il fuso orario esatto. Il list of timezones è completo, con centinaia di fusi orari individuali in tutto il mondo. I fusi orari di PHP terranno automaticamente conto dell'ora legale.
Quando l'utente genera un datetime nell'app Web, crea un oggetto datetime PHP nel fuso orario del profilo dell'utente. Quindi utilizzare il metodo setTimezone
per modificare l'oggetto DateTime nel fuso orario UTC. Ora hai il datetime dell'utente in UTC ed è possibile memorizzare il valore nel database. Utilizzare il metodo DateTime format
per esprimere i dati come una stringa nel formato accettato da MySQL.
Così l'utente genera un datetime, e ti fanno un oggetto PHP datetime nel fuso orario specificato dell'utente:
// set using an include file for user profile
$user_timezone = new DateTimeZone('America/New_York');
// 1st arg in format accepted by PHP strtotime
$date_object1 = new DateTime('8/9/2012 5:19 PM', $user_timezone);
$date_object1->setTimezone(new DateTimeZone('UTC'));
$formated_string = $date_object1->format('Y-m-d H:i:s');
$query_string="INSERT INTO `t_table1` (`datetime1`) VALUES('$formated_string')";
Quando si recupera il valore dal database, costruire in UTC e poi convertire in tempo dell'utente zona.
$query_string="SELECT `datetime1` FROM `t_table1`";
$date_object1=new DateTime($datetime_string_from_mysql, new DateTimeZone('UTC');
$date_object1->setTimezone($user_timezone);
$string_for_display_in_application = $date_object1->format('m/d/Y g:i a');
Usando questo metodo, i valori datetime sono sempre memorizzati in UTC all'interno del db, e l'utente sperimenta sempre i valori nel fuso orario sua/il suo profilo. PHP correggerà l'ora legale se necessario per ciascun fuso orario.
Un getcha: questa spiegazione non copre il datatype di timestamp MySQL. Raccomando di utilizzare il datetime di MySQL per memorizzare i valori datetime, non il datatype timestamp. Il datatype del timestamp è trattato nel manuale here.
Edit: È possibile produrre una matrice contenente ogni corda fuso orario PHP utilizzando listIdentifiers, che è un metodo statico della classe DateTimeZone.
possibile duplicato di [Visualizzazione delle informazioni sul fuso orario e sul fuso orario dell'utente (cosa, non come)] (http://stackoverflow.com/questions/274823/displaying-time-and-timezone-information-to-the-user -what-not-how) o http://stackoverflow.com/questions/1285523/date-and-time-handling-in-applications-serving-clients-in-multiple-time-zones?rq=1 –
UTC (precedentemente noto come GMT) e l'ora locale di Londra sono * non * la stessa cosa, lo sai. Londra osserva l'ora legale. –
Lo so (io vivo nel Regno Unito), avrebbe dovuto rendere più chiaro anche l'ora legale. Ogni volta che penso di averlo risolto, l'ora legale sembra sempre di intralciare :) –