Аз не съм гуру на python или Django, така че може би някой може да отговори по-добре от мен. Но все пак ще направя предположение.
Казахте, че го съхранявате в Django DateTimeField
, което според документите, които сте посочили
, съхранява го като datetime
на Python .
Разглеждане на документите за datetime
, мисля, че ключът е в разбирането на разликата между "наивни" и "съзнателни" стойности.
И след това, проучвайки допълнително, попаднах на този отлична справка
. Уверете се, че сте прочели втория раздел, „Наивни и осъзнати обекти за дата и време“. Това дава малко контекст за това колко от това се контролира от Django. По принцип, като зададете USE_TZ = true
, вие молите Django да използва aware datetime вместо наивни такива.
Тогава погледнах отново към въпроса ти. Казахте, че правите следното:
dt = datetime.fromtimestamp(secs)
dt = dt.replace(tzinfo=utc)
Разглеждайки fromtimestamp функционална документация, намерих този къс текст:
Така че мисля, че бихте могли да направите това:
dt = datetime.fromtimestamp(secs, tz=utc)
След това, точно под тази функция, документите показват utcfromtimestamp
функция, така че може би трябва да бъде:
dt = datetime.utcfromtimestamp(secs)
Не знам достатъчно за python, за да знам дали те са еквивалентни или не, но можете да опитате и да видите дали едното от тях има значение.
Надяваме се, че едно от тях ще направи разликата. Ако не, моля, уведомете ме. Запознат съм отблизо с датата/часа в JavaScript и .Net, но винаги се интересувам как тези нюанси се проявяват по различен начин в други платформи, като Python.
Актуализиране
По отношение на MySQL частта на въпроса, разгледайте тази цигулка .
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;
Резултати:
DATE UNIX_TIMESTAMP(`DATE`)
June, 13 2013 13:50:02+0000 1371131402
June, 13 2013 13:50:02+0000 1371127802
Изглежда, че поведението на UNIX_TIMESTAMP
функцията наистина е засегната от MySQL TIME_ZONE
настройка. Това не е толкова изненадващо, тъй като е в документацията. Това, което е изненадващо, е, че низовият изход на datetime
има една и съща UTC стойност, независимо от настройката.
Ето какво мисля, че се случва. В документите за UNIX_TIMESTAMP
функция, пише:
Имайте предвид, че не пише, че може да бъде DATETIME
- пише, че може да бъде DATETIME
низ . Така че мисля, че действителната стойност се преобразува имплицитно в низ, преди да бъде предадена във функцията.
Така че сега вижте тази актуализирана цигулка който преобразува изрично.
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;
Резултати:
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
Можете да видите, че когато се преобразува в символни данни, премахва изместването. Така че, разбира се, сега има смисъл, когато UNIX_TIMESTAMP
приема тази стойност като вход, приема настройката на местната часова зона и по този начин получава различно времеви печат за UTC.
Не съм сигурен дали това ще ви помогне или не. Трябва да се задълбочите повече в това как Django извиква MySQL както за четене, така и за запис. Всъщност използва ли UNIX_TIMESTAMP
функция? Или точно това направихте при тестването?