【问题标题】:Python datetime.utcnow() returning incorrect datetimePython datetime.utcnow() 返回不正确的日期时间
【发布时间】:2015-04-18 21:06:00
【问题描述】:
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

【问题讨论】:

  • 你的时区是什么?
  • time.timezone 说什么,它是否适合您的时区(以秒为单位)?
  • 返回 2015-02-17 23:58:44.761000。当前 UTC 时间是:00:58,而不是 23:58。
  • 你的机器上time.time()time.gmtime()GetSystemTimeAsFileTime()返回的值是否一致?

标签: python python-2.7 datetime utc


【解决方案1】:

我知道我迟到了五年,但今晚我遇到了同样的问题。根据我的经验,该问题的解决方案是使用可感知的 UTC 日期时间:

utc_dt_aware = datetime.datetime.now(datetime.timezone.utc)

如果你用谷歌搜索“utcnow() 错误”,这是你得到的第一个结果,所以我认为无论如何回答都会很好。

【讨论】:

    【解决方案2】:

    datetime.utcnow() 使用操作系统提供的值。

    datetime.utcnow() 在 Python 2 上使用 gettimeofday(2)time.time()(以及 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]))
    

    这是在 Windows based on CPython source 上调用 GetSystemTimeAsFileTime() 的(未经测试的)代码:

    #!/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() on Python 2的代码。

    【讨论】:

      【解决方案3】:

      问题只出现在 utc 时间 (Python3)。

      例如系统时间:

      $ date
      
      Wed Jul 15 10:44:26 BST 2015
      

      使用 datetime.now() 时 Python 时间正确:

      >>> 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 - Converting UTC and timezone to local time

      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)

      【讨论】:

      • 您为什么认为utcnow() 不正确?除非您当地时区的 UTC 偏移量为零; UTC 时间将与本地时间不同。无关:您可以使用datetime.now(timezone) 来获取给定时区的当前时间。您提供的参考资料不好。对于第一个;在那里阅读我的 cmets。
      • 不清楚为什么您提供了指向 “datetime 缺乏针对 UTC 的具体 tzinfo 实现”的链接 Python 问题(在 Python 3 中已修复;很容易解决在 Python 2 中;如果您已经在使用 pytz,则根本不用担心。
      • BST 的 utc 偏移量非零,因此 预计 utcnow() 返回的日期时间与 now() 不同:“本地时间 = UTC 时间 + UTC 偏移量”跨度>
      • 错误utcnow() 在全世界都是一样的(+/- 时钟同步)。您当地的时区是什么并不重要。 UTC 时间保持不变,例如,现在是 2015-07-16T23:41:30Z (UTC)。如果您在计算机上运行datetime.utcnow(),那么无论您的时区如何,您都应该获得相似的时间(如果您在 POSIX 系统上;您可以使用TZ envvar 轻松更改您的时区,并亲自查看utcnow() 不会改变(如果您更改本地时区,now() 可能会发生变化)。如果您使用“正确”时区,.utcnow() 可能会跳跃大约 26 秒,但这是另一个问题。
      • 你对UTC有一些不正确的先入之见。在大多数情况下,您应该更喜欢使用 UTC(这比使用本地时间要容易得多),例如 Find if 24 hrs have passed between datetimes - Python。见,Daylight saving time and time zone best practices
      【解决方案4】:

      我知道我很晚才回复这个问题。

      我最近尝试过这样做,因此我建议使用 datetime.now() 而不是 datetime.utcnow()。对于我运行良好的简单应用程序。

      【讨论】:

      • 顾名思义,utcnow() 和 now() 不是一回事。 datetime.now() 返回本地日期。
      猜你喜欢
      • 2017-06-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-03-10
      • 2015-12-19
      • 2014-04-10
      • 2019-02-05
      相关资源
      最近更新 更多