1

今天我和一些同事试图正确地将日期时间转换为非本地时区的时间戳。经过多次讨论,我们仍然不确定如何在一般意义上正确地将日期时间转换为时间戳,并且仅部分确定如何为我们的用例执行此操作: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)

结果以四种方式计算:

  1. time.mktime(dt.timetuple())
  2. time.mktime(dt.utctimetuple())
  3. calendar.timegm(dt.timetuple())
  4. 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())通常是正确的方法——除非它是一个幼稚的本地时间。好的,我可以解决这个问题......除了我看不到如何区分本地天真时间与任何其他天真时间,这使得无法将任意日期时间对象正确转换为时间戳?真的是这样吗,还是我错过了什么?

4

1 回答 1

0

我看不出你如何区分当地的天真时间和任何其他天真的时间

确切地。如您所知,naive 意味着“没有附加时区信息”,因此timegm被迫推断缺少的信息,并且您的结果表明它推断 naive datetimes 为 UTC。

正如评论中所说,附加了 TZ 的时间应该被视为烫手山芋 - 您应该在获得输入后立即转换为 UTC,并在输出给用户之前转换为本地时间。从长远来看,这将为您节省很多心痛。

于 2013-02-16T05:13:21.640 回答