2012-07-19 197 views
1

今天我和一些同事试图将日期时间正确转换为非本地时区中的时间戳。经过多次讨论,我们仍然不确定如何在一般意义上正确地将日期时间转换为时间戳,并且只是部分确定如何为我们的用例做到这一点:America/New_York中的日期时间实例时区从pytz。将datetime转换为unix时间戳

所以,我想我会通过一些排列运行,并试图经验搞清楚,因为阅读文档,并试图逻辑思维它没有得到我的任何地方。

这里的输入数据:

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())是通常正确的方式 - 除非它是一个天真的本地时间。好吧,我可以处理这个......除了我没有看到如何从任何其他天真的时间消除局部天真的时间,这使得无法正确地将任意日期时间对象转换为时间戳?这是真的吗,还是我错过了什么?

+1

看看这个:http://lucumr.pocoo.org/2011/7/15/eppur-si-muove/“”“总是测量并存储时间UTC如果需要记录下的时间。被采取,单独存储。不存储当地时间+时区信息!“”“” – monkut 2012-07-19 05:37:44

+0

我同意@monkut,但如果您必须传输时间,它也应该是UTC。 [日期时间转换到POSIX时间]的 – 2012-07-19 05:56:06

+0

可能重复(http://stackoverflow.com/questions/255035/converting-datetime-to-posix-time) – 2012-07-19 05:57:21

回答

0

我不明白你怎么可以从任何其他的幼稚时间

究竟歧义本地天真的时间。如你所知,天真的意思是“没有附带时区信息”,所以timegm被迫推断缺失的信息,你的结果表明它推断天真的日期时间是UTC。

正如在评论中说,TZ附着时间应像对待一个烫手的山芋 - 你应该尽快你输入转换为UTC,只是你输出给用户之前转换为本地。从长远来看,这会为你节省很多心痛。

相关问题