J'ai longuement traité cette situation dans une application PHP/MySQL que j'ai écrite pour un opérateur de jet privé il y a un peu plus d'un an. Il existe différentes stratégies pour gérer les fuseaux horaires sur ces deux plates-formes, mais je vais vous expliquer comment je l'ai fait. Je configure le serveur MySQL sur UTC et exécute chaque script PHP dans le fuseau horaire spécifié par l'utilisateur lors du processus d'inscription pour le profil utilisateur.
MySQL et PHP (PHP 5.2 et supérieur) ont tous deux des types de données datetime natifs. Le datetime de MySQL est un type de données primitif, tandis que PHP 5.2 et supérieur offre le Classe DateTime . Le type de données MySQL datetime n'inclut pas de métadonnées pour le fuseau horaire, mais un objet PHP DateTime inclut toujours un fuseau horaire. Si le constructeur PHP datetime ne spécifie pas le fuseau horaire facultatif dans le deuxième argument, le constructeur PHP datetime utilise la variable d'environnement php.
MySQL et PHP ont tous deux un fuseau horaire par défaut défini dans les fichiers de configuration. MySQL utilise le datetime défini dans le fichier de configuration pour chaque connexion à la base de données, sauf si l'utilisateur spécifie un fuseau horaire différent après le démarrage de la connexion avec la commande SET time_zone = [timezone];
. PHP définit également une variable d'environnement de fuseau horaire pour chaque script en utilisant le fuseau horaire défini dans le fichier de configuration du serveur, et cette variable d'environnement peut être remplacée à l'aide de la fonction PHP date_default_timezone_set()
après le démarrage du script.
La classe PHP DateTime a une propriété appelée timezone , qui est un objet PHP DateTimeZone . L'objet DateTimeZone est spécifié à l'aide d'une chaîne pour le fuseau horaire exact. La liste des fuseaux horaires est complet, avec des centaines de fuseaux horaires individuels à travers le monde. Les fuseaux horaires PHP prendront automatiquement en compte l'heure d'été.
Lorsque l'utilisateur génère une date/heure dans l'application Web, construisez un objet date/heure PHP dans le fuseau horaire du profil de l'utilisateur. Ensuite, utilisez le setTimezone
pour modifier l'objet DateTime sur le fuseau horaire UTC. Vous avez maintenant la date et l'heure de l'utilisateur en UTC et vous pouvez stocker la valeur dans la base de données. Utilisez le format DateTime format
méthode pour exprimer les données sous forme de chaîne dans le format accepté par MySQL.
Ainsi, l'utilisateur génère une date/heure et vous créez un objet date/heure PHP dans le fuseau horaire spécifié par l'utilisateur :
// 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')";
Lorsque vous récupérez la valeur de la base de données, construisez-la en UTC, puis convertissez-la dans le fuseau horaire de l'utilisateur.
$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');
En utilisant cette méthode, vos valeurs datetime sont toujours stockées en UTC à l'intérieur de la base de données, et l'utilisateur expérimente toujours les valeurs dans le fuseau horaire de son profil. PHP corrigera l'heure d'été si nécessaire pour chaque fuseau horaire.
Un piège :cette explication ne couvre pas le type de données d'horodatage MySQL. Je recommande d'utiliser le type de date datetime MySQL pour stocker les valeurs datetime, pas le type de données timestamp. Le type de données d'horodatage est traité dans le manuel ici .
Modifier : Vous pouvez produire un tableau contenant chaque chaîne de fuseau horaire PHP en utilisant listIdentifiers , qui est une méthode statique de la classe DateTimeZone.