今天我和一些同事试图正确地将日期时间转换为非本地时区的时间戳。经过多次讨论,我们仍然不确定如何在一般意义上正确地将日期时间转换为时间戳,并且仅部分确定如何为我们的用例执行此操作:America/New_York 中的日期时间实例来自 pytz 的时区。
所以,我想我会经历一些排列并尝试凭经验弄清楚,因为阅读文档并试图从逻辑上推理出来并没有让我有任何收获。
这是输入数据:
pst = pytz.timezone('America/Los_Angeles')
est = pytz.timezone('America/New_York')
utc = pytz.timezone('UTC')
epoch = int(time.time())
# local time for me is Pacific
local_naive = datetime.datetime.fromtimestamp(epoch)
local_aware = datetime.datetime.fromtimestamp(epoch, pst)
est_aware = datetime.datetime.fromtimestamp(epoch, est)
utc_naive = datetime.datetime.utcfromtimestamp(epoch)
utc_aware = datetime.datetime.fromtimestamp(epoch, utc)
结果以四种方式计算:
- time.mktime(dt.timetuple())
- time.mktime(dt.utctimetuple())
- calendar.timegm(dt.timetuple())
- calendar.timegm(dt.utctimetuple())
我意识到其中一些本质上是荒谬的,但我试图做到完整:)。
这是输出。这diff=
部分是为了帮助显示不正确的转换。
now epoch : 1342671099
est aware mktime(timetuple) : 1342681899 diff=-10800
local aware mktime(timetuple) : 1342671099 diff=0
local naive mktime(timetuple) : 1342671099 diff=0
utc aware mktime(timetuple) : 1342699899 diff=-28800
utc naive mktime(timetuple) : 1342696299 diff=-25200
est aware mktime(utctimetuple): 1342699899 diff=-28800
local aware mktime(utctimetuple): 1342699899 diff=-28800
local naive mktime(utctimetuple): 1342674699 diff=-3600
utc aware mktime(utctimetuple): 1342699899 diff=-28800
utc naive mktime(utctimetuple): 1342699899 diff=-28800
est aware timegm(timetuple) : 1342656699 diff=14400
local aware timegm(timetuple) : 1342645899 diff=25200
local naive timegm(timetuple) : 1342645899 diff=25200
utc aware timegm(timetuple) : 1342671099 diff=0
utc naive timegm(timetuple) : 1342671099 diff=0
est aware timegm(utctimetuple): 1342671099 diff=0
local aware timegm(utctimetuple): 1342671099 diff=0
local naive timegm(utctimetuple): 1342645899 diff=25200
utc aware timegm(utctimetuple): 1342671099 diff=0
utc naive timegm(utctimetuple): 1342671099 diff=0
从我从这个输出中可以看出,一般来说,调用 calendar.timegm(dt.utctimetuple())通常是正确的方法——除非它是一个幼稚的本地时间。好的,我可以解决这个问题......除了我看不到如何区分本地天真时间与任何其他天真时间,这使得无法将任意日期时间对象正确转换为时间戳?真的是这样吗,还是我错过了什么?