Nie jestem pytonem ani guru Django, więc może ktoś może odpowiedzieć lepiej niż ja. Ale i tak zgadnę.
Powiedziałeś, że przechowujesz to w DateTimeField
Django , który zgodnie z dokumentami, do których się odwołujesz
, przechowuje go jako Pythonową datetime
.
Patrząc na dokumentację datetime
, myślę, że kluczem jest zrozumienie różnicy między wartościami „naiwnymi” i „świadomymi”.
A potem, prowadząc dalsze badania, natknąłem się na to doskonałe źródło
. Koniecznie przeczytaj drugą sekcję, „Naiwne i świadome obiekty daty/godziny”. To daje trochę kontekstu, jak wiele z tego jest kontrolowanych przez Django. Zasadniczo, ustawiając USE_TZ = true
, prosisz Django o użycie aware daty i godziny zamiast naiwnych jedynki.
Więc wtedy spojrzałem wstecz na twoje pytanie. Powiedziałeś, że robisz następujące rzeczy:
dt = datetime.fromtimestamp(secs)
dt = dt.replace(tzinfo=utc)
Patrząc na fromtimestamp dokumentacja funkcji, znalazłem ten fragment tekstu:
Myślę więc, że możesz to zrobić:
dt = datetime.fromtimestamp(secs, tz=utc)
Z drugiej strony, tuż pod tą funkcją, dokumentacja pokazuje utcfromtimestamp
funkcja, więc może powinno być:
dt = datetime.utcfromtimestamp(secs)
Nie wiem wystarczająco dużo o Pythonie, aby wiedzieć, czy są one równoważne, czy nie, ale możesz spróbować i sprawdzić, czy któryś z nich robi różnicę.
Mam nadzieję, że jeden z nich zrobi różnicę. Jeśli nie, daj mi znać. Jestem dogłębnie zaznajomiony z datą/godziną w JavaScript i .Net, ale zawsze interesuje mnie, jak te niuanse rozgrywają się inaczej na innych platformach, takich jak Python.
Aktualizacja
Jeśli chodzi o część pytania dotyczącą MySQL, spójrz na te skrzypce .
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;
Wyniki:
DATE UNIX_TIMESTAMP(`DATE`)
June, 13 2013 13:50:02+0000 1371131402
June, 13 2013 13:50:02+0000 1371127802
Wydawałoby się, że zachowanie UNIX_TIMESTAMP
funkcja jest rzeczywiście dotknięta przez MySQL TIME_ZONE
ustawienie. To nie jest takie zaskakujące, ponieważ znajduje się w dokumentacji. Zaskakujące jest to, że wynik ciągu datetime
ma taką samą wartość UTC niezależnie od ustawienia.
Oto, co moim zdaniem się dzieje. W dokumentacji UNIX_TIMESTAMP
funkcja, mówi:
Zauważ, że nie mówi, że może to być DATETIME
- mówi, że może to być DATETIME
ciąg . Myślę więc, że rzeczywista wartość jest niejawnie konwertowana na ciąg znaków przed przekazaniem jej do funkcji.
A teraz spójrz na te zaktualizowane skrzypce który konwertuje w sposób jawny.
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;
Wyniki:
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
Widać, że kiedy konwertuje na dane znakowe, usuwa przesunięcie. Więc oczywiście ma to sens teraz, gdy UNIX_TIMESTAMP
przyjmuje tę wartość jako dane wejściowe, przyjmuje ustawienie lokalnej strefy czasowej, a tym samym otrzymuje inny znacznik czasu UTC.
Nie jestem pewien, czy to ci pomoże, czy nie. Musisz dokładniej zagłębić się w to, jak Django wywołuje MySQL zarówno do odczytu, jak i do zapisu. Czy faktycznie używa UNIX_TIMESTAMP
? funkcjonować? A może właśnie to zrobiłeś podczas testów?