Python datetime.utcnow() возвращает неверное время

datetime.utcnow()

Этот вызов возвращает неверное дата и время, отложенное с UTC/GMT на 1 час (регистрация: http://www.worldtimeserver.com/current_time_in_UTC.asp). Он работает так, как должно быть?

Например, он возвращается прямо сейчас:

2015-02-17 23:58:44.761000.

Текущее время UTC: 00:58, а не 23:58

Спасибо,

Ответ 1

datetime.utcnow() использует значения, предоставленные ОС.

datetime.utcnow() использует gettimeofday(2) или time.time() на Python 2 (и gmtime(3), чтобы преобразовать результат в разлагаемое время).

time.time() использует gettimeofday(2), ftime(3), time(2). Новые версии CPython могут использовать clock_gettime(2), GetSystemTimeAsFileTime().

Вы можете проверить самосогласованность следующим образом:

#!/usr/bin/env python
import time
from datetime import datetime, timedelta

print(datetime.utcnow())
print(datetime(1970, 1, 1) + timedelta(seconds=time.time()))
print(datetime(*time.gmtime()[:6]))

Здесь (не проверенный) код, который вызывает GetSystemTimeAsFileTime() в Windows на основе источника CPython:

#!/usr/bin/env python
import ctypes.wintypes
from datetime import datetime, timedelta

def utcnow_microseconds():
    system_time = ctypes.wintypes.FILETIME()
    ctypes.windll.kernel32.GetSystemTimeAsFileTime(ctypes.byref(system_time))
    large = (system_time.dwHighDateTime << 32) + system_time.dwLowDateTime
    return large // 10 - 11644473600000000

print(datetime(1970, 1, 1) + timedelta(microseconds=utcnow_microseconds()))

Здесь код, который вызывает clock_gettime() на Python 2.

Ответ 2

Я знаю, что я очень поздно отвечаю на это.

Я пробовал делать это недавно, поэтому я предлагаю использовать datetime.now() вместо datetime.utcnow(). Для моего простого приложения, которое отлично работает.

Ответ 3

Проблема возникает только с utc time (Python3).

например. Системное время:

$ date

Wed Jul 15 10:44:26 BST 2015

Время использования Python при использовании datetime.now():

>>> datetime.now()

datetime.datetime(2015, 7, 15, 10, 44, 30, 775840)

... Но неверно на один час при использовании datetime.utcnow():

>>> datetime.utcnow()

datetime.datetime(2015, 7, 15, 9, 44, 32, 599823)

Проблема UTC заключается в том, что она не знает мой часовой пояс.

Вы должны сказать это с помощью модуля часового пояса, называемого pytz:

>>> import pytz
>>> mytz = pytz.timezone('Europe/London')
>>> pytz.utc.localize(datetime.utcnow(), is_dst=None).astimezone(mytz)

datetime.datetime(2015, 7, 15, 11, 3, 43, 688681, tzinfo=<DstTzInfo 'Europe/London' BST+1:00:00 DST>)

Литература:

pytz - Преобразование UTC и часовой пояс в локальное время

https://opensourcehacker.com/2008/06/30/relativity-of-time-shortcomings-in-python-datetime-and-workaround/

http://sweemengs-tech-world.blogspot.co.uk/2010/05/get-correct-datetime-value-for-python.html

http://bugs.python.org/issue5094)