2010-06-06 5 views
2

J'ai une application qui stocke actuellement les horodatages dans les valeurs MySQL DATETIME et TIMESTAMP. Cependant, l'application doit pouvoir accepter les données des utilisateurs dans plusieurs fuseaux horaires et afficher les horodatages dans le fuseau horaire des autres utilisateurs. En tant que tel, voici comment je prévois de modifier la demande; J'apprécierais toutes les suggestions pour améliorer l'approche.Migration de fuseau horaire PHP/MySQL

modifications de base de données

  • Tous les horodatages seront converties en valeurs DATETIME; ceci afin d'assurer une approche cohérente et d'éviter que MySQL essaie de faire des choses intelligentes et de convertir les fuseaux horaires (je veux garder la conversion en PHP, car cela implique moins de modification de l'application, et sera plus portable quand j'arriverai à échapper à MySQL).
  • Toutes les valeurs DATETIME seront ajustées pour les convertir en temps UTC (actuellement tous dans Australian EST)

Modifications Recherche

  • Tous à remplacer l'utilisation de NOW() avec UTC_TIMESTAMP() dans requêtes, triggers, fonctions, etc.

modifications d'application

  • L'application doit stocker le fuseau horaire et le format de date préféré (par ex. Etats-Unis vs le reste du monde)
  • Tous les horodateurs seront convertis en fonction des paramètres utilisateur avant d'être affichés
  • Tous les horodateurs d'entrée seront converties en UTC en fonction des paramètres utilisateur avant d'être entrée

supplémentaires notes

  • formats Converting seront effectués au niveau de l'application pour plusieurs raisons principales
    • l'un Pproach pour convertir les fuseaux horaires varie de DB à DB, de sorte qu'il sera non-portable (et j'espère vraiment migrer loin de MySQL dans un futur proche).
    • timestamps MySQL ont des applications limitées aux dates autorisées (~ 1970 à ~ 2038)
    • TimeStamps MySQL ont d'autres attributs indésirables, y compris le comportement d'auto-mise à jour bizarre (sinon soigneusement désactivé) et la sensibilité aux paramètres de la zone du serveur (et Je soupçonne que je pourrais les visser quand je migre vers Amazon plus tard dans l'année). Le choix de changer toutes les valeurs de datetime actuelles, et d'utiliser UTC_TIMESTAMP() au lieu de NOW() est d'éviter tout problème avec les configurations de serveur/fuseau horaire de connexion, qui modifierait NOW() mais laisserait UTC_TIMESTAMP() seul; voir ci-dessous pour un exemple.

Exemple de UTC_TIMESTAMP() vs NOW()

mysql> set time_zone = 'Australia/Canberra'; 
Query OK, 0 rows affected (0.06 sec) 

mysql> select now(), utc_timestamp(); 
+---------------------+---------------------+ 
| now()    | utc_timestamp()  | 
+---------------------+---------------------+ 
| 2010-06-06 14:31:36 | 2010-06-06 04:31:36 | 
+---------------------+---------------------+ 
1 row in set (0.00 sec) 

mysql> set time_zone = 'America/Los_Angeles'; 
Query OK, 0 rows affected (0.00 sec) 

mysql> select now(), utc_timestamp(); 
+---------------------+---------------------+ 
| now()    | utc_timestamp()  | 
+---------------------+---------------------+ 
| 2010-06-05 21:31:43 | 2010-06-06 04:31:43 | 
+---------------------+---------------------+ 
1 row in set (0.00 sec) 

est-il quelque chose que je suis absent ici, ou que quelqu'un a de meilleures suggestions pour l'approche?

Répondre

1

Y at-il quelque chose qui me manque ici, ou quelqu'un a-t-il de meilleures suggestions pour l'approche?

Vous faites peut-être trop de travail.

Tant que vous connaissez le fuseau horaire de l'horodatage enregistré, vous pouvez facilement le convertir en un autre fuseau horaire. Si vous utilisez une version moderne de PHP, le DateTime class intégré inclut une gestion complète des fuseaux horaires.

Vous n'êtes pas nécessairement besoin pour convertir tous vos fuseaux horaires dans la base de données si elles sont déjà considérés comme des heures locales et il a été correctement configuré pour utiliser un fuseau horaire local, à savoir qu'ils sont déjà auto-cohérent . Tout ce que vous devez faire est simplement de convertir les heures locales en fuseau horaire de l'utilisateur lors du rendu de l'heure, et stocker le fuseau horaire enregistré avec l'horodatage (pour les autres utilisateurs affichant l'heure dans le fuseau horaire du propriétaire d'horodatage). Sinon, votre plan semble bien pensé et complet.

+0

Les valeurs datetime sont cohérentes en ce moment, mais lorsque je migre des serveurs, je dois définir le serveur pour être dans le même fuseau horaire, même si c'est ailleurs (je prévois de passer à Amazon's Emplacement de Singapour, maintenant qu'il est opérationnel). Si je laisse le serveur dans son fuseau horaire réel, la valeur de NOW() changera, de sorte qu'il y aura une incohérence entre les timestamps, alors que TIMESTAMP_UTC() sera toujours le même –

+0

Sinon, oui, PHP 5.2 avec le DateTime classe rend les choses beaucoup plus faciles qu'elles ne l'étaient :) Ce sera la partie de l'approche au niveau de l'application. –

+0

Un changement de fuseau horaire de serveur en attente (surtout lorsque vous ne contrôlez pas le serveur) est une très bonne raison pour passer à l'UTC. – Charles