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

Hvorfor påvirker Django-tidszoneindstillingen epoketid?

Jeg er ingen python- eller Django-guru, så måske kan nogen svare bedre end mig. Men jeg vil gætte på det alligevel.

Du sagde, at du gemte det i et Django DateTimeField , som ifølge de dokumenter, du refererede til , gemmer det som en Python datetime .

Ser på dokumenterne for datetime Jeg tror, ​​at nøglen er at forstå forskellen mellem "naive" og "bevidste" værdier.

Og så forskede jeg videre, stødte jeg på denne fremragende reference . Sørg for at læse det andet afsnit, "Naive og bevidste datetime-objekter". Det giver en smule kontekst til, hvor meget af dette, der bliver kontrolleret af Django. Grundlæggende ved at indstille USE_TZ = true , du beder Django om at bruge aware datetimes i stedet for naiv dem.

Så så kiggede jeg tilbage på dit spørgsmål. Du sagde, at du gjorde følgende:

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

Ser på fromtimestamp funktionsdokumentation, fandt jeg denne smule tekst:

Så jeg tror, ​​du kunne gøre dette:

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

Så igen, lige under den funktion, viser dokumenterne utcfromtimestamp funktion, så det burde måske være:

dt = datetime.utcfromtimestamp(secs)

Jeg ved ikke nok om python til at vide, om disse er ækvivalente eller ej, men du kan prøve og se, om begge gør en forskel.

Forhåbentlig vil en af ​​disse gøre en forskel. Hvis ikke, så lad mig det vide. Jeg er indgående bekendt med dato/klokkeslæt i JavaScript og i .Net, men jeg er altid interesseret i, hvordan disse nuancer udspiller sig anderledes på andre platforme, såsom Python.

Opdater

Angående MySQL-delen af ​​spørgsmålet, tag et kig på denne violin .

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;

Resultater:

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

Det ser ud til, at adfærden for UNIX_TIMESTAMP funktionen er faktisk påvirket af MySQL TIME_ZONE indstilling. Det er ikke så overraskende, da det står i dokumentationen. Hvad der er overraskende er, at strengoutputtet af datetime har den samme UTC-værdi uanset indstillingen.

Her er, hvad jeg tror, ​​der sker. I dokumenterne for UNIX_TIMESTAMP funktion, står der:

Bemærk, at der ikke står, at det kan være en DATETIME - der står, at det kan være en DATETIME streng . Så jeg tror, ​​at den faktiske værdi implicit konverteres til en streng, før den overføres til funktionen.

Så se nu på denne opdaterede violin der konverterer eksplicit.

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;

Resultater:

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

Du kan se, at når den konverterer til tegndata, fjerner den offset. Så selvfølgelig giver det mening nu, når UNIX_TIMESTAMP tager denne værdi som input, den antager den lokale tidszoneindstilling og får dermed et andet UTC-tidsstempel.

Ikke sikker på, om dette vil hjælpe dig eller ej. Du skal grave mere ind i præcis, hvordan Django kalder MySQL til både læsning og skrivning. Bruger den faktisk UNIX_TIMESTAMP fungere? Eller var det bare det, du gjorde i testen?




  1. Hvorfor returnerer PDO::lastInsertId 0?

  2. tæl top 10 mest forekommende værdier i en kolonne i mysql

  3. SQL Injection i Java og MySQL ved brug af flere forespørgsler

  4. MYSQL ind i outfil adgang nægtet - men min bruger har ALT adgang.. og mappen er CHMOD 777