[英]Python Timestamp + Datetime Conversion
自从纪元值为1459952824358
起,我就具有UNIX毫秒时间戳记的测试记录
我正在使用fastavro库编写Python 2.x程序。 这需要1459952824358
整数UNIX毫秒时间戳,并将其转换为本地日期时间值2016-04-06T09:27:04.358000
。 当我尝试将其转换回整数UNIX毫秒时间戳值时,我的工作时间减少了一个小时。 我可以使用普通的Python日期时间在fastavro库之外复制此转换问题:
import datetime
import time
raw = 1459952824358
local_dt = datetime.datetime.fromtimestamp(raw / 1000.0)
local_dt.isoformat() # '2016-04-06T09:27:04.358000'
back = int((local_dt - datetime.datetime.fromtimestamp(0)).total_seconds() * 1.0e3)
back - raw # 3600000
我可以转换为UTC日期时间并成功返回:
import datetime
import time
raw = 1459952824358
utc_dt = datetime.datetime.utcfromtimestamp(raw / 1000.0)
utc_dt.isoformat() # '2016-04-06T14:27:04.358000'
back = int((utc_dt - datetime.datetime.utcfromtimestamp(0)).total_seconds() * 1.0e3)
back - raw # 0
奇怪的是,我的系统设置为CST或UTC-6,但是Python产生的本地日期时间比UTC值低了五个小时,而不是六个小时。
虽然我的特定项目需要Python 2兼容性,但我尝试使用Python 3 timestamp
功能,该功能可以正确地返回原始时间戳值,而不会出现小时数漂移,但是即使我的系统即使本地日期时间也比UTC时间短5个小时。设置为CST或UTC-6。
import datetime
import time
raw = 1459952824358
local_dt = datetime.datetime.fromtimestamp(raw / 1000.0)
local_dt.isoformat() # '2016-04-06T09:27:04.358000'
back = int(local_dt.timestamp() * 1000)
back - raw # 0
我在同一台笔记本电脑上尝试了Java 9中的相同示例,只是看它产生了什么:
import java.time.*
long raw = 1459952824358L;
Instant i = Instant.ofEpochMilli(raw)
ZonedDateTime zdtUtc = ZonedDateTime.ofInstant(i, ZoneOffset.UTC)
// UPDATE: This line was my original attempt. It was wrong because it uses the current daylight savings setting, not the one of the given date.
ZonedDateTime zdtLocal = zdtUtc.withZoneSameInstant(ZonedDateTime.now().getOffset())
// This next line will choose the current geography, but choose the daylight savings setting based on the date, which is what I expected.
ZonedDateTime zdtLocal = zdtUtc.withZoneSameInstant(ZoneId.systemDefault())
long deltaFromUtc = zdtUtc.toInstant().toEpochMilli() - raw
long deltaFromLocal = zdtLocal.toInstant().toEpochMilli() - raw
无论utc / local如何,它都会返回确切的原始时间戳值。
更新:基本上,Python 2.x在没有额外库的情况下无法将本地日期时间值正确转换为UTC。 Python 3.x可以,而Python 2.x则具有额外的库来执行此操作,但是开箱即用却不能。
tl; dr :您的测量处于关闭状态,而不是日期时间:您正在比较来自不同时区的两次,因此结果应该是时区之间的差值。
所以这就是为什么最好在UTC中工作:
在Python 2.7中:
使用原始数据:
>>> print datetime.datetime.utcfromtimestamp(raw/1000.0)
... print datetime.datetime.fromtimestamp(raw/1000.0)
...
2016-04-06 14:27:04.358000
2016-04-06 07:27:04.358000
7小时不同
使用夏令时以外的修改日期:
>>> print datetime.datetime.utcfromtimestamp(1456952824)
... print datetime.datetime.fromtimestamp(1456952824)
...
2016-03-02 21:07:04
2016-03-02 13:07:04
8小时不同
发生这种情况是因为本地时间的raw
和0
处于不同的时区(夏令时与标准时间):
>>> print datetime.datetime.utcfromtimestamp(raw/1000.0)
... print datetime.datetime.fromtimestamp(raw/1000.0)
...
2016-04-06 14:27:04.358000
2016-04-06 07:27:04.358000
>>> print datetime.datetime.utcfromtimestamp(0)
... print datetime.datetime.fromtimestamp(0)
...
1970-01-01 00:00:00
1969-12-31 16:00:00
如果您坚持使用utc,就没有问题。
但是即使我的系统设置为CST或UTC-6,本地日期时间仍然比UTC时间短5个小时。
因为在该raw
日期,您的本地时间为CDT(-5):
user@TS-E31:~$ date --date @1459952824
Wed Apr 6 07:27:04 PDT 2016
user@TS-E31:~$ date --date @0
Wed Dec 31 16:00:00 PST 1969
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.