Python datetime转Epoch结果不一致问题及标准转换方法咨询
差异原因:时区依赖导致的不一致
你遇到的问题核心在于:time.mktime()这个函数会把没有时区信息的datetime对象(naive datetime)当成当前运行环境的本地时区时间来转换,而repl.it服务器的时区设置和你本地Python 2.7环境的时区不一样,最终导致计算出的epoch时间戳出现差异。
具体来说,你用datetime.strptime(t, "%Y%m%d%H%M%S")得到的是一个没有时区标记的datetime,它只表示“2018-05-15 10:25:00”这个时间点,但并没有说明这是哪个时区的时间。当你调用time.mktime(d.timetuple())时,它会默认把这个时间当成当前环境的本地时间,转成对应的epoch秒数。如果repl.it的时区是UTC,而你本地是另一个时区(比如带夏令时的时区或UTC+5时区),两者转换后的结果自然会差出对应时区的偏移量,也就是你看到的18000秒(5小时)的差异。
推荐的datetime转Epoch时间戳方法
要避免这种环境依赖的问题,最稳妥的方式是明确时区信息,不要使用无时区的naive datetime。下面分两种场景给出方案:
场景1:你的时间字符串代表UTC时间
如果20180515102500是UTC时间,直接给datetime绑定UTC时区后再转换:
# Python 3 版本 from datetime import datetime, timezone t = '20180515102500' # 解析后添加UTC时区标记 d = datetime.strptime(t, "%Y%m%d%H%M%S").replace(tzinfo=timezone.utc) # 转换为毫秒级时间戳 millis_since_epoch = int(d.timestamp() * 1000) print(millis_since_epoch)
# Python 2 版本(Python 2无datetime.timestamp()方法) from datetime import datetime, timedelta t = '20180515102500' d = datetime.strptime(t, "%Y%m%d%H%M%S") # 计算UTC时间距epoch的总秒数 epoch = datetime(1970, 1, 1) millis_since_epoch = int((d - epoch).total_seconds() * 1000) print(millis_since_epoch)
场景2:你的时间字符串代表本地时区时间
如果这个时间是你本地时区的时间,建议用pytz库(Python 2/3通用)明确指定时区,避免依赖系统时区:
# 先安装pytz:pip install pytz from datetime import datetime import pytz t = '20180515102500' # 替换成你的实际本地时区,比如Asia/Shanghai、America/New_York等 local_tz = pytz.timezone('Asia/Shanghai') # 给naive datetime绑定本地时区,is_dst=None会自动检测夏令时问题 d = local_tz.localize(datetime.strptime(t, "%Y%m%d%H%M%S"), is_dst=None) # Python 3 转换为毫秒时间戳 millis_since_epoch = int(d.timestamp() * 1000) # Python 2 转换方式 # millis_since_epoch = int((d - pytz.utc.localize(datetime(1970, 1, 1))).total_seconds() * 1000) print(millis_since_epoch)
总结
不管哪种场景,核心都是给datetime对象明确时区信息,这样不管在哪个环境运行,转换后的epoch时间戳都会保持一致,不会再出现因时区差异导致的结果不同。
内容的提问来源于stack exchange,提问作者user1179299

