Mysql
 sql >> Base de données >  >> RDS >> Mysql

Pourquoi le paramètre de fuseau horaire de Django affecte-t-il l'heure d'époque ?

Je ne suis pas un python ou un gourou de Django, alors peut-être que quelqu'un peut mieux répondre que moi. Mais je vais quand même essayer de deviner.

Vous avez dit que vous le stockiez dans un Django DateTimeField , qui selon les documents que vous avez référencés , le stocke en tant que Python datetime .

En regardant la documentation pour datetime , je pense que la clé est de comprendre la différence entre les valeurs "naïves" et "conscientes".

Et puis en poursuivant mes recherches, je suis tombé sur cette excellente référence . Assurez-vous de lire la deuxième section, "Objets datetime naïfs et conscients". Cela donne un peu de contexte à la quantité de ceci contrôlée par Django. Fondamentalement, en définissant USE_TZ = true , vous demandez à Django d'utiliser aware datetimes au lieu de naïf ceux.

Alors j'ai regardé en arrière votre question. Vous avez dit que vous faisiez ce qui suit :

dt = datetime.fromtimestamp(secs)
dt = dt.replace(tzinfo=utc)

En regardant le fromtimestamp documentation de la fonction, j'ai trouvé ce bout de texte :

Je pense donc que vous pourriez faire ceci :

dt = datetime.fromtimestamp(secs, tz=utc)

Là encore, juste en dessous de cette fonction, la documentation affiche utcfromtimestamp fonction, alors peut-être que ça devrait être :

dt = datetime.utcfromtimestamp(secs)

Je n'en sais pas assez sur Python pour savoir si ceux-ci sont équivalents ou non, mais vous pouvez essayer de voir si l'un ou l'autre fait une différence.

Espérons que l'un d'entre eux fera une différence. Si ce n'est pas le cas, veuillez me le faire savoir. Je connais intimement la date/heure en JavaScript et en .Net, mais je suis toujours intéressé par la façon dont ces nuances se jouent différemment sur d'autres plates-formes, telles que Python.

Mettre à jour

En ce qui concerne la partie MySQL de la question, jetez un œil à ce violon .

CREATE TABLE foo (`date` DATETIME);
INSERT INTO foo (`date`) VALUES (FROM_UNIXTIME(1371131402));

SET TIME_ZONE="+00:00";
select `date`, UNIX_TIMESTAMP(`date`) from foo;

SET TIME_ZONE="+01:00";
select `date`, UNIX_TIMESTAMP(`date`) from foo;

Résultats :

DATE                           UNIX_TIMESTAMP(`DATE`)
June, 13 2013 13:50:02+0000    1371131402
June, 13 2013 13:50:02+0000    1371127802

Il semblerait que le comportement de UNIX_TIMESTAMP la fonction est en effet affectée par MySQL TIME_ZONE paramètre. Ce n'est pas si surprenant, puisque c'est dans la documentation. Ce qui est surprenant, c'est que la sortie de chaîne de datetime a la même valeur UTC quel que soit le paramètre.

Voici ce que je pense qu'il se passe. Dans les docs pour UNIX_TIMESTAMP fonction, il dit :

Notez qu'il ne dit pas qu'il peut s'agir d'un DATETIME - il dit qu'il peut s'agir d'un DATETIME chaîne . Je pense donc que la valeur réelle est implicitement convertie en chaîne avant d'être transmise à la fonction.

Alors maintenant, regardez ce violon mis à jour qui convertit explicitement.

SET TIME_ZONE="+00:00";
select `date`, convert(`date`, char), UNIX_TIMESTAMP(convert(`date`, char)) from foo;

SET TIME_ZONE="+01:00";
select `date`, convert(`date`, char), UNIX_TIMESTAMP(convert(`date`, char)) from foo;

Résultats :

DATE                           CONVERT(`DATE`, CHAR)  UNIX_TIMESTAMP(CONVERT(`DATE`, CHAR))
June, 13 2013 13:50:02+0000    2013-06-13 13:50:02    1371131402
June, 13 2013 13:50:02+0000    2013-06-13 13:50:02    1371127802

Vous pouvez voir que lorsqu'il est converti en données de caractères, il supprime le décalage. Alors bien sûr, il est logique maintenant que lorsque UNIX_TIMESTAMP prend cette valeur en entrée, il suppose le paramètre de fuseau horaire local et obtient ainsi un horodatage UTC différent.

Je ne sais pas si cela vous aidera ou non. Vous devez approfondir la manière exacte dont Django appelle MySQL pour la lecture et l'écriture. Utilise-t-il réellement le UNIX_TIMESTAMP fonction? Ou était-ce simplement ce que vous avez fait lors des tests ?