【问题标题】:Is there an inverse function for time.gmtime() that parses a UTC tuple to seconds since the epoch?time.gmtime() 是否有一个反函数,可以将 UTC 元组解析为自纪元以来的秒数?
【发布时间】:2010-09-12 21:43:05
【问题描述】:

python 的时间模块似乎有点随意。例如,这里有一个方法列表,来自文档字符串:

time() -- return current time in seconds since the Epoch as a float
clock() -- return CPU time since process start as a float
sleep() -- delay for a number of seconds given as a float
gmtime() -- convert seconds since Epoch to UTC tuple
localtime() -- convert seconds since Epoch to local time tuple
asctime() -- convert time tuple to string
ctime() -- convert time in seconds to string
mktime() -- convert local time tuple to seconds since Epoch
strftime() -- convert time tuple to string according to format specification
strptime() -- parse string to time tuple according to format specification
tzset() -- change the local timezone

看看localtime()和它的逆mktime(),为什么gmtime()没有逆?

额外问题:您将方法命名为什么?你将如何实现它?

【问题讨论】:

    标签: python


    【解决方案1】:

    实际上有一个反函数,但出于某种奇怪的原因,它位于calendar 模块中:calendar.timegm()。我列出了这个answer中的函数。

    【讨论】:

    • calendar.timegm(datetime.datetime.utcnow().utctimetuple()) 是获取 UTC 时间戳的唯一方法。
    • Python:包括电池,但有时电池本身没有组装。
    • @erikcw: 或者只是在使用 Unix 纪元的系统上(在我知道的每个系统上)上的 time.time()。 +/- float/int 转换。
    【解决方案2】:

    mktime 文档在这里有点误导,没有任何意义说它是按本地时间计算的,而是根据提供的元组从 Epoch 计算秒数 - 无论您的计算机位置如何。

    如果您确实想将 utc_tuple 转换为本地时间,您可以执行以下操作:

    >>> time.ctime(time.time())
    'Fri Sep 13 12:40:08 2013'
    
    >>> utc_tuple = time.gmtime()
    >>> time.ctime(time.mktime(utc_tuple))
    'Fri Sep 13 10:40:11 2013'
    
    >>> time.ctime(time.mktime(utc_tuple) - time.timezone)
    'Fri Sep 13 12:40:11 2013'
    


    也许更准确的问题是如何将 utc_tuple 转换为 local_tuple。 我会称之为 gm_tuple_to_local_tuple(我更喜欢长而描述性的名称):

    >>> time.localtime(time.mktime(utc_tuple) - time.timezone)
    time.struct_time(tm_year=2013, tm_mon=9, tm_mday=13, tm_hour=12, tm_min=40, tm_sec=11, tm_wday=4, tm_yday=256, tm_isdst=1)
    


    验证:

    >>> time.ctime(time.mktime(time.localtime(time.mktime(utc_tuple) - time.timezone)))
    'Fri Sep 13 12:40:11 2013'    
    

    希望这会有所帮助, 伊利亚。

    【讨论】:

    • 这个答案是错误的。演示:assert time.gmtime(10**9) == (2001,9,9, 1,46,40, 6,252,0)assert time.mktime((2001,9,9, 1,46,40, 6,252,0)) == 10**9 - 4*3600(最后一个只在某些系统上是真的,当然,取决于当地的时区)。原因:mktime 确实考虑了当地时区。
    【解决方案3】:

    我只是 Python 的新手,但这是我的方法。

    def mkgmtime(fields):
        now = int(time.time())
        gmt = list(time.gmtime(now))
        gmt[8] = time.localtime(now).tm_isdst
        disp = now - time.mktime(tuple(gmt))
        return disp + time.mktime(fields)
    

    还有,我提议的函数名称也是如此。 :-) 每次都重新计算disp 很重要,以防夏令时值发生变化等。 (Jython 需要转换回元组。CPython 似乎不需要它。)

    这太糟糕了,因为time.gmtime 总是将 DST 标志设置为 false。不过,我讨厌代码。必须有更好的方法来做到这一点。可能还有一些我还没有得到的极端案例。

    【讨论】:

      【解决方案4】:

      我一直认为时间和日期时间模块有点不连贯。无论如何,这是 mktime 的倒数

      import time
      def mkgmtime(t):
          """Convert UTC tuple to seconds since Epoch"""
          return time.mktime(t)-time.timezone
      

      【讨论】:

      • 弄清楚是使用 time.timezone 还是 time.altzone 是困难的部分。 :-)
      • 对于非 Python 人员:time.timezone 是非 DST 时间增量。 time.altzone 是 DST 时间增量。据我所知,除了调用 localtime() 之外,没有真正的方法可以判断时间戳是否落在 DST 上。
      • 我第二个 Jester,我一般你不能减去时区,因为 DST 不在时区,这只会让你得到本地时间(不考虑 DST)
      • 1. time.mktime() 需要 local 时间,而 calendar.timegm() 需要 UTC 时间元组。它可能会导致范围错误。 2. 一些本地时间不明确或不存在,即,要么有两个对应的时间戳,要么没有——mktime() 可能会在 DST 转换时返回错误的结果。 3. -time.timezone 可能与 the corresponding utc offset 不同,原因是 DST (altzone) 或 t 时间的 UTC 偏移量与当前 UTC 偏移量不同。
      猜你喜欢
      • 2019-12-04
      • 2010-09-13
      • 2013-08-09
      • 2023-03-03
      • 1970-01-01
      • 2013-08-19
      • 1970-01-01
      • 2020-11-17
      相关资源
      最近更新 更多