时区的麻烦 - 所有时区都是本地时区吗?

时间:2014-08-11 14:57:42

标签: python python-2.7 datetime timezone python-datetime

我在python中遇到时区问题并且有一个奇怪的例子...... 我使用的是Python 2.7.2

import time
import datetime
import pytz
utc = pytz.utc
est = pytz.timezone('US/Eastern')
mst = pytz.timezone('US/Mountain')
print 'UTC time',time.mktime(datetime.datetime(1970, 01, 01, 0, 0, 0, tzinfo=utc).timetuple())/3600
print 'EST time',time.mktime(datetime.datetime(1970, 01, 01, 0, 0, 0, tzinfo=est).timetuple())/3600
print 'MST time',time.mktime(datetime.datetime(1970, 01, 01, 0, 0, 0, tzinfo=mst).timetuple())/3600

我认为我应该为三个例子(UTC,EST,MST)获得0.0,5.0和7.0 - 但是我在所有三个案例中得到5.0(我的计算机在EST中运行)。

此外

time.mktime(time.gmtime(0))

返回18000.0(5小时) - 所以 - 显式请求元组的gmtime然后转换为epoch返回5小时。我的python发行版有time.time()和time.gmtime(),但不是time.timegm()

因此,如果我在MST中收到客户的数据 - 并且想要生成UTC时代 - 我是否必须假装时间戳在EST中然后再添加5小时?

这是strptime丢掉时区信息的结果吗?

1 个答案:

答案 0 :(得分:2)

timetuple()(以及所有其他基于struct-tm的函数)丢弃时区信息;即,时间元组数据结构根本没有时区字段。它旨在将日期时间分解为其组件显示字段,因此它从未真正设计用于计算时间值。尽可能保持日期时间格式的价值。

>>> datetime.datetime(1970, 01, 01, 0, 0, 0, tzinfo=utc)
datetime.datetime(1970, 1, 1, 0, 0, tzinfo=<UTC>)
>>> datetime.datetime(1970, 01, 01, 0, 0, 0, tzinfo=utc).timetuple()
time.struct_time(tm_year=1970, tm_mon=1, tm_mday=1, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=3, tm_yday=1, tm_isdst=0)

此外,您不应该只是将tzinfo直接插入日期时间构造函数 - 根据这个答案,它并不总能给出正确的结果:dateutil and pytz give different results。使用localize()代替,让pytz有机会根据任何适用的时区规则按摩数据。

以下代码将从MST转换为EST:

>>> now = mst.localize(datetime.datetime(1970, 01, 01, 0, 0, 0))
>>> now
datetime.datetime(1970, 1, 1, 0, 0, tzinfo=<DstTzInfo 'US/Mountain' MST-1 day, 17:00:00 STD>)
>>> now.astimezone(est)
datetime.datetime(1970, 1, 1, 2, 0, tzinfo=<DstTzInfo 'US/Eastern' EST-1 day, 19:00:00 STD>)

我不知道这是否会处理所有角落案件。例如,您经常会看到围绕夏令时过渡的奇怪事情。如果遇到问题,请开始搜索第三方时间库。