首页 文章

将datetime转换为Unix时间戳并在python中将其转换回来

提问于
浏览
143

我有 dt = datetime(2013,9,1,11) ,我想获得这个datetime对象的Unix时间戳 .

当我做 dt - datetime(1970,1,1)).total_seconds() 时,我得到了时间戳 1378033200 .

当使用 datetime.fromtimestamp 将其转换回来时,我得到 datetime.datetime(2013, 9, 1, 6, 0) .

小时不匹配 . 我在这里想念的是什么?

9 回答

  • 2

    你在这里错过的是时区 .

    大概你有五个小时的UTC时间,所以2013-09-01T11:00:00本地和2013-09-01T06:00:00Z是同一时间 .

    您需要阅读datetime文档的顶部,这些文档解释了时区和"naive"和"aware"对象 .

    如果你的原始天真日期时间是UTC,恢复它的方法是使用utcfromtimestamp而不是 fromtimestamp .

    另一方面,如果您原来的天真日期时间是本地的,那么您不应该首先从它中减去UTC时间戳;请改用 datetime.fromtimestamp(0) .

    或者,如果您有一个知道日期时间对象,则需要在两侧使用本地(感知)时期,或者显式转换为UTC和从UTC转换 .

    如果您拥有或可以升级到Python 3.3或更高版本,您可以通过使用timestamp方法避免所有这些问题,而不是试图弄清楚如何自己完成 . 即使你不这样做,你也可以考虑borrowing its source code .

    (如果你可以等到Python 3.4,看起来像PEP 341可能会进入最终版本,这意味着JF Sebastian和我在评论中讨论的所有东西应该只与stdlib一起工作,并且正在工作在Unix和Windows上都是一样的 . )

  • 2

    solution is

    import time
    import datetime
    d = datetime.date(2015,1,5)
    
    unixtime = time.mktime(d.timetuple())
    
  • 107

    而不是这个表达式来创建 dt 的POSIX时间戳,

    (dt - datetime(1970,1,1)).total_seconds()
    

    用这个:

    int(dt.strftime("%s"))
    

    我使用第二种方法在您的示例中得到了正确的答案 .

    编辑:一些跟进...经过一些评论(见下文),我很惊讶 %s 中缺少对 %s 的支持或文档 . 这是我发现的:

    Python source for datetimetime 中,字符串 STRFTIME_FORMAT_CODES 告诉我们:

    "Other codes may be available on your platform.
     See documentation for the C library strftime function."
    

    所以现在如果我们 man strftime (在Mac OS X等BSD系统上),你会发现对 %s 的支持:

    "%s is replaced by the number of seconds since the Epoch, UTC (see mktime(3))."
    

    无论如何,这就是 %s 在它所使用的系统上工作的原因 . 但是这里有更好的解决方案来接受OP _2932906的接受 .

  • 49

    如果你想将python日期时间转换为epoch以来的秒数,你应该明确地做到:

    >>> import datetime
    >>> datetime.datetime(2012,04,01,0,0).strftime('%s')
    '1333234800'
    >>> (datetime.datetime(2012,04,01,0,0) - datetime.datetime(1970,1,1)).total_seconds()
    1333238400.0
    

    在Python 3.3中,您可以使用timestamp()代替:

    >>> import datetime
    >>> datetime.datetime(2012,4,1,0,0).timestamp()
    1333234800.0
    
  • 3

    如果您的datetime对象表示UTC时间,请不要使用time.mktime,因为它假定元组在您的本地时区 . 相反,使用calendar.timegm:

    >>> import datetime, calendar
    >>> d = datetime.datetime(1970, 1, 1, 0, 1, 0)
    >>> calendar.timegm(d.timetuple())
    60
    
  • 1

    使用UTC时区:

    time_stamp = calendar.timegm(dt.timetuple())
    
    datetime.utcfromtimestamp(time_stamp)
    
  • 3

    好吧,当转换为TO unix时间戳时,python基本上是假设UTC,但在转换回来时它会给你一个转换为你当地时区的日期 .

    看到这个问题/答案; Get timezone used by datetime.datetime.fromtimestamp()

  • 36

    您错过了时区信息(已经回答,同意)

    arrow package 允许在日期时间内避免这种折磨;它已经编写,测试,pypi发布,cross-python(2.6 - 3.xx) .

    所有你需要的: pip install arrow (或添加到依赖项)

    解决您的案例

    dt = datetime(2013,9,1,11)
    arrow.get(dt).timestamp
    # >>> 1378033200
    
    bc = arrow.get(1378033200).datetime
    print(bc)
    # >>> datetime.datetime(2013, 9, 1, 11, 0, tzinfo=tzutc())
    print(bc.isoformat())
    # >>> '2013-09-01T11:00:00+00:00'
    
  • 80
    def dt2ts(dt, utc=False):
        if utc:
            return calendar.timegm(dt.timetuple())
        if dt.tzinfo is None:
            return int(time.mktime(dt.timetuple()))
        utc_dt = dt.astimezone(tz.tzutc()).timetuple()
        return calendar.timegm(utc_dt)
    

    如果你想要UTC时间戳: time.mktime 仅适用于 local dt . 使用 calendar.timegm 是安全的,但dt必须是utc区域,所以将区域更改为utc . 如果UTC中的dt只使用 calendar.timegm .

相关问题