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

Utilizzo dei fusi orari in un'applicazione Web PHP

Ho affrontato questa situazione ampiamente 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. Ho impostato il server MySQL su UTC ed eseguo ogni script PHP nel fuso orario specificato dall'utente durante il processo di registrazione per il profilo utente.

MySQL e PHP (PHP 5.2 e versioni successive) hanno entrambi tipi di dati datetime nativi. Datetime di MySQL è un tipo di dati primitivo, mentre PHP 5.2 e versioni successive offrono il Classe DateTime . Il tipo di dati MySQL datetime non include i metadati per il fuso orario, ma un oggetto PHP DateTime include sempre un fuso orario. Se il costruttore PHP datetime non specifica il fuso orario opzionale nel secondo argomento, il costruttore PHP datetime utilizza la variabile d'ambiente php.

Sia MySQL che PHP hanno il fuso orario predefinito impostato nei file di configurazione. MySQL utilizza datetime impostato nel file di configurazione per ogni connessione db a meno che l'utente non specifichi un diverso fuso orario dopo che la connessione è stata avviata con il comando SET time_zone = [timezone]; . PHP imposta anche una variabile di ambiente del fuso orario per ogni script utilizzando il fuso orario impostato nel file di configurazione del server e questa variabile di ambiente può essere sovrascritta utilizzando la funzione PHP date_default_timezone_set() dopo l'avvio dello script.

La classe PHP DateTime ha una proprietà chiamata timezone , che è un oggetto PHP DateTimeZone . L'oggetto DateTimeZone viene specificato utilizzando una stringa per il fuso orario esatto. L'elenco dei fusi orari è completo, con centinaia di fusi orari individuali in tutto il mondo. I fusi orari PHP terranno automaticamente conto dell'ora legale.

Quando l'utente genera un datetime nell'app Web, costruisci un oggetto datetime PHP nel fuso orario del profilo dell'utente. Quindi usa setTimezone metodo per modificare l'oggetto DateTime nel fuso orario UTC. Ora hai la data e l'ora dell'utente in UTC e puoi archiviare il valore nel database. Usa il format DateTime metodo per esprimere i dati come una stringa nel formato accettato da MySQL.

Quindi l'utente genera un datetime e tu crei un oggetto datetime PHP nel fuso orario specificato dall'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 recuperi il valore dal database, costruisci in UTC e poi converti nel fuso orario dell'utente.

$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 tuoi valori datetime vengono sempre archiviati in UTC all'interno del db e l'utente sperimenta sempre i valori nel fuso orario del proprio profilo. PHP correggerà l'ora legale, se necessario, per ogni fuso orario.

One gotcha:questa spiegazione non copre il tipo di dati del timestamp MySQL. Raccomando di utilizzare il tipo di data MySQL datetime per memorizzare i valori datetime, non il tipo di dati timestamp. Il tipo di dati timestamp è trattato nel manuale qui .

Modifica: Puoi produrre un array contenente ogni stringa di fuso orario PHP utilizzando listIdentifiers , che è un metodo statico della classe DateTimeZone.