Python日期时间转换为Epoch时间戳

11
t='20180515102500'
d=datetime.strptime(t, "%Y%m%d%H%M%S")
millis_since_epoch = int(time.mktime(d.timetuple())) * 1000
print(millis_since_epoch)

repl.it上输出:1526379900000 (Python 3.6.1),而本地环境上输出:1526397900000(Python 2.7.14)。

为什么会有这种差异?如何推荐将datetime对象转换为epoch时间?


3
您正在使用不带时区信息的日期时间。假设repl.it运行的时区比您本地时区早5个小时,因此其结果会相差5个小时。如果您不想使用“该计算机的本地时间”,则需要决定您想要什么样的时间信息,例如:UTC?带有偏移量或时区信息的时间戳?请确认您的选择。 - abarnert
1
无论如何,将datetime对象转换为距离epoch的偏移量的推荐方法是只需在其上调用timestamp()(然后乘以1000如果您想要毫秒而不是秒),或者减去epoch(作为datetime)并使用timedelta结果。但是,这两种方法都无法解决您的问题;您最终会得到相同的结果。 - abarnert
顺便问一下,为什么你要将 float 转换为 int,然后再乘以 1000 呢?即使你在毫秒计数,你实际上是否确实想要确保没有亚秒精度呢? - abarnert
4个回答

12
你的问题在于你正在使用简单的datetime (以及struct_tm等)对象。所以你想知道2018年5月15日10:25:00在“本机上的任何本地时区”距离Unix纪元有多远。如果在两台相隔五小时的计算机上运行,你将得到相差5*3600*1000毫秒的结果。
建议的方法是:
d.timestamp() # returns difference from epoch as float seconds

…或者:

d - datetime.fromtimestamp(0) # returns difference as timedelta

显然,你可以将它们转换为毫秒的浮点数,或者其他你需要的东西。

但是这两种方式都不会对此产生任何影响,因为你仍在使用原始的datetime对象。(至少你没有混合使用time模块中的其他类型并丢失精度,但是你没有解决问题。)


你的问题的解决方案取决于你想要做什么。这些是UTC时间戳吗?它们是一些已知时区的时间戳,你已经了解了吗?

如果所有东西都是UTC时间,最好的方法是明确创建UTC对象,但最简单的方法(特别是如果你需要你的代码在2.7上运行)是:

d - datetime.utcfromtimestamp(0)

这将给你一个天真的日期时间,表示自纪元以来0秒UTC,并从你的天真日期时间中减去它,表示自纪元以来X秒UTC,因此你会得到一个时间差,表示X秒(具体而言,是17666天,37500秒),不考虑系统使用的时区。
或者,对你现有代码的最小更改是使用utctimetuple而不是timetuple,这样可以以更复杂的方式完成相同的操作。

谢谢,我“假设”Python中的datetime与Java的LocalDateTime类似,没有时区。 是的,那些是UTC时间戳。 - user1179299
Python有一个类来处理naive-local、带时区和UTC日期时间。你现在使用的是naive-local。但如果你期望它的行为类似于Java中的LocalDateTime,那么你为什么会感到惊讶它的行为像Java的LocalDateTime一样呢? - abarnert
LocalDateTime始终没有时区,而Python的DateTime则可以支持不同的时区。我曾经认为它们是相同的。 - user1179299

7

在Python 3.6中:

datetime.timestamp()

例如:

举个例子:

import datetime

timestamp = datetime.datetime.now().timestamp()

5

试试这个:

t='20180515102500'
d=datetime.datetime.strptime(t, "%Y%m%d%H%M%S")
print(d)
epoch = datetime.datetime.utcfromtimestamp(0)


def unix_time_millis(dt):
  return (dt - epoch).total_seconds() * 1000

unix_time_millis(d)

如果这有帮助,请告诉我!


0
t = datetime.strptime(gr_dt_string, "%Y-%m-%dT%H:%M:%S")
if six.PY2:
    gr_mili = int((t - datetime.fromtimestamp(0)).total_seconds()) * 1000
else:
    gr_mili = int(t.timestamp() * 1000)

3
你好,下面是翻译的结果:请问您需要解释您的答案吗? - D. O.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接