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

bri*_*ter 159 python datetime timestamp

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

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

datetime.fromtimestamp我把它转换回来的时候datetime.datetime(2013, 9, 1, 6, 0).

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

Dmi*_*nov 124

解决方案是

import time
import datetime
d = datetime.date(2015,1,5)

unixtime = time.mktime(d.timetuple())
Run Code Online (Sandbox Code Playgroud)

  • 它假定`d`是一个天真的日期/日期时间对象,代表当地时间(如果操作系统不提供历史tz db,它可能会因模糊时间或过去/未来日期而失败(UTC偏移可能在过去有所不同)在当地时区)).[更多选项](http://stackoverflow.com/q/8777753/4279). (12认同)
  • 看起来没有人会想到浮点解决方案.这对每个人来说都很明显吗? (6认同)
  • 这会减少微秒.可能很有趣. (4认同)
  • python 3.9 中错误...```int(mytime.timestamp())``` (2认同)

aba*_*ert 89

你在这里错过的是时区.

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

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

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

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

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

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

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


Dar*_*one 53

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

(dt - datetime(1970,1,1)).total_seconds()
Run Code Online (Sandbox Code Playgroud)

用这个:

int(dt.strftime("%s"))
Run Code Online (Sandbox Code Playgroud)

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

编辑:一些后续......经过一番评论(见下文),我很好奇的是,缺乏支持或文档%sstrftime.这是我发现的:

Python源datetimetime,串STRFTIME_FORMAT_CODES告诉我们:

"Other codes may be available on your platform.
 See documentation for the C library strftime function."
Run Code Online (Sandbox Code Playgroud)

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

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

无论如何,这就是为什么%s在它所使用的系统上工作的原因.但OP有更好的解决方案(将时区考虑在内).请参阅@ abarnert在此处接受的答案.

  • 这是无证件的行为(我相信).例如,在Windows上,它会导致"无效的格式字符串". (3认同)
  • 你永远不应该使用`%s`,因为你只会使用你所在系统的本地化系统时间。如果您想获得真正的 UNIX 时间戳,您需要使用 `.timestamp()`。 (2认同)

Fra*_*sta 48

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

>>> 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
Run Code Online (Sandbox Code Playgroud)

在Python 3.3+中你可以使用timestamp():

>>> import datetime
>>> datetime.datetime(2012,4,1,0,0).timestamp()
1333234800.0
Run Code Online (Sandbox Code Playgroud)

  • `timestamp()` 的结果是浮点数有什么特殊原因吗?将其转换为“int”安全吗?IE 的返回值“timestamp()”是否会返回一些我应该考虑的小数? (6认同)
  • 不考虑时区。 (4认同)
  • 您不想使用`%s`,因为它将被本地化为您当前所在系统的时钟.你应该只使用`.timestamp()`来获得正确的Epoch/UNIX时间. (2认同)
  • `%s`在Windows系统上不起作用(`ValueError:无效的格式字符串`) (2认同)

小智 11

使用 UTC 时区:

time_stamp = calendar.timegm(dt.timetuple())

datetime.utcfromtimestamp(time_stamp)
Run Code Online (Sandbox Code Playgroud)


max*_*kov 6

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

arrow允许避免这种日期时间的折磨;它已经编写、测试、pypi 发布、跨 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'
Run Code Online (Sandbox Code Playgroud)


Mat*_*mer 6

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

>>> import datetime, calendar
>>> d = datetime.datetime(1970, 1, 1, 0, 1, 0)
>>> calendar.timegm(d.timetuple())
60
Run Code Online (Sandbox Code Playgroud)