Je l'ai compris pour mes besoins. Je vais résumer ce que j'ai appris (désolé, ces notes sont verbeuses; elles sont autant pour ma future référence que pour toute autre chose).
Contrairement à ce que j'ai dit dans l'un de mes commentaires précédents, les champs DATETIME et TIMESTAMP font se comportent différemment. Les champs TIMESTAMP (comme l'indiquent les documents) prennent tout ce que vous leur envoyez au format "AAAA-MM-JJ hh: mm: ss" et le convertit de votre fuseau horaire actuel en heure UTC. L'inverse se produit de manière transparente chaque fois que vous récupérez les données. Les champs DATETIME n'effectuent pas cette conversion. Ils prennent tout ce que vous leur envoyez et le stockent directement.
Ni les types de champ DATETIME ni TIMESTAMP ne peuvent stocker avec précision les données dans un fuseau horaire qui respecte l'heure d'été . Si vous stockez "2009-11-01 01:30:00", les champs n'ont aucun moyen de distinguer la version de 1h30 que vous vouliez - la version -04: 00 ou -05: 00.
Ok, donc nous devons stocker nos données dans un fuseau horaire non DST (comme UTC). Les champs TIMESTAMP ne peuvent pas gérer ces données avec précision pour des raisons que je vais vous expliquer: si votre système est réglé sur un fuseau horaire DST, ce que vous mettez dans TIMESTAMP peut ne pas être ce que vous récupérez. Même si vous lui envoyez des données que vous avez déjà converties en UTC, il assumera toujours les données dans votre fuseau horaire local et effectuera une autre conversion en UTC. Cet aller-retour local-à-UTC-retour-local imposé par TIMESTAMP est avec perte lorsque votre fuseau horaire local observe l'heure d'été (depuis "2009-11-01 01:30:00" correspond à 2 heures possibles différentes).
Avec DATETIME, vous pouvez stocker vos données dans n'importe quel fuseau horaire de votre choix et être sûr que vous récupérerez tout ce que vous envoyez (vous ne serez pas obligé de participer aux conversions aller-retour avec perte que les champs TIMESTAMP vous imposent). La solution consiste donc à utiliser un champ DATETIME et avant d'enregistrer sur le terrain, convertir le fuseau horaire de votre système dans la zone non-DST dans laquelle vous souhaitez l'enregistrer (je pense que UTC est probablement la meilleure option). Cela vous permet de créer la logique de conversion dans votre langage de script afin de pouvoir enregistrer explicitement l'équivalent UTC de "2009-11-01 01:30:00 -04: 00" ou "" 2009-11-01 01:30: 00 -05: 00 ".
Une autre chose importante à noter est que les fonctions mathématiques date / heure de MySQL ne fonctionnent pas correctement autour des limites de l'heure d'été si vous stockez vos dates dans un TZ DST. Raison de plus pour économiser en UTC.
En un mot, je fais maintenant ceci:
Lors de la récupération des données de la base de données:
Interprétez explicitement les données de la base de données comme UTC en dehors de MySQL afin d'obtenir un horodatage Unix précis. J'utilise la fonction strtotime () de PHP ou sa classe DateTime pour cela. Cela ne peut pas être fait de manière fiable à l'intérieur de MySQL en utilisant les fonctions CONVERT_TZ () ou UNIX_TIMESTAMP () de MySQL car CONVERT_TZ affichera uniquement une valeur 'YYYY-MM-DD hh: mm: ss' qui souffre de problèmes d'ambiguïté, et UNIX_TIMESTAMP () suppose son l'entrée est dans le fuseau horaire du système, et non dans le fuseau horaire dans lequel les données ont été réellement stockées (UTC).
Lors du stockage des données dans la base de données:
Convertissez votre date en heure UTC précise que vous désirez en dehors de MySQL. Par exemple: avec la classe DateTime de PHP, vous pouvez spécifier "2009-11-01 1:30:00 EST" distinctement de "2009-11-01 1:30:00 EDT", puis le convertir en UTC et enregistrer l'heure UTC correcte dans votre champ DATETIME.
Phew. Merci beaucoup pour la contribution et l'aide de tous. Espérons que cela évite à quelqu'un d'autre des maux de tête sur la route.
BTW, je vois cela sur MySQL 5.0.22 et 5.0.27