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?