Python:根据时间戳获取时区及夏时制
我写了这样的代码,用来根据夏令时(DST)获取特定时间点的时区:
def getTimeZoneFromEpoch(epoch)
if time.daylight and time.gmtime(epoch).tm_isdst==1:
return -time.altzone/3600.0
else:
return -time.timezone/3600.0
但是我不确定这样做是否正确,实际上我现在的结果错了1个小时。也许我应该在这段代码中交换altzone和timezone的位置,但这不是我从Python的帮助文档(时间模块)中理解到的:
timezone -- difference in seconds between UTC and local standard time
altzone -- difference in seconds between UTC and local DST time
tm_isdst
1 if summer time is in effect, 0 if not, and -1 if unknown
我是不是搞错了什么?
3 个回答
1
谢谢你的帮助,除了你建议的那两种方法,我还找到了一种更灵活(可能也更兼容)的版本,它可以接受时区对象(或者直接使用本地时区),并返回UTC偏移量。
有一个叫做AmbiguousTimeError的部分让我感到困惑,不过我对它做了一些处理,让它在所有情况下(算是)都能正常工作。
from datetime import datetime
import pytz
from tzlocal import get_localzone
def getUtcOffsetByEpoch(epoch, tz=None):
if not tz:
tz = get_localzone()
delta = 0
while True:
try:
return tz.utcoffset(datetime.fromtimestamp(epoch + delta)).total_seconds()
except pytz.exceptions.AmbiguousTimeError:## FIXME
#d = datetime.fromtimestamp(epoch+3600)
#print('AmbiguousTimeError', d.year, d.month, d.day, d.hour, d.minute, d.second)
delta += 3600
print('delta = %s'%delta)
except (
ValueError,
OverflowError,
):
return tz._utcoffset.total_seconds()
4
简单来说,使用 time.localtime()
而不是 time.gmtime()
。
问题出在你使用了 gmtime()
,下面这个程序的结果就能说明这一点。
from time import *
def getTimeZoneFromEpoch(epoch):
if daylight and gmtime(epoch).tm_isdst==1:
return -altzone/3600.0
else:
return -timezone/3600.0
print " tm_isdst of tm_isdst of time zone's\n" + \
' epoch gmtime(epoch) localtime(epoch) offset'
for d in ('13/03/2011', # DST start date in USA
'14/03/2011',
'',
'06/11/2011', # DST end date in USA
'07/11/2011',
'',
'27/03/2011', # DST start date in Europe
'28/03/2011',
'',
'30/10/2011', # DST end date in Europe
'31/10/2011'):
if d:
ds = strptime(d,'%d/%m/%Y')
epoch = mktime(ds)
lt = localtime(epoch)
gt = gmtime(epoch)
print '%s %s %12s %11s %7s %17s' % (d,ds.tm_isdst,epoch,gt.tm_isdst,lt.tm_isdst,getTimeZoneFromEpoch(epoch))
else:
print
我把时钟设置在“UTC-07:00 洛基山脉”时区,这个时区的夏令时从2011年3月13日开始,到2011年11月6日结束,结果是:
tm_isdst of tm_isdst of time zone's
epoch gmtime(epoch) localtime(epoch) offset
13/03/2011 -1 1299999600.0 0 0 -7.0
14/03/2011 -1 1300082400.0 0 1 -7.0
06/11/2011 -1 1320559200.0 0 1 -7.0
07/11/2011 -1 1320649200.0 0 0 -7.0
27/03/2011 -1 1301205600.0 0 1 -7.0
28/03/2011 -1 1301292000.0 0 1 -7.0
30/10/2011 -1 1319954400.0 0 1 -7.0
31/10/2011 -1 1320040800.0 0 1 -7.0
我把时钟设置在“UTC+01:00 西欧大陆”时区,这个时区的夏令时从2011年3月27日开始,到2011年10月30日结束,结果是:
tm_isdst of tm_isdst of time zone's
epoch gmtime(epoch) localtime(epoch) offset
13/03/2011 -1 1299970800.0 0 0 1.0
14/03/2011 -1 1300057200.0 0 0 1.0
06/11/2011 -1 1320534000.0 0 0 1.0
07/11/2011 -1 1320620400.0 0 0 1.0
27/03/2011 -1 1301180400.0 0 0 1.0
28/03/2011 -1 1301263200.0 0 1 1.0
30/10/2011 -1 1319925600.0 0 1 1.0
31/10/2011 -1 1320015600.0 0 0 1.0
4
我测试了这段代码,用来获取虚拟机的本地时间与协调世界时(UTC)的时差。顺便说一下,这个时差在测量的那一刻才是有效的。我不确定你的代码是否和这个功能相同。
def local_ephemeral_UTC_offset(epoch_time=None):
u"Returns a datetime.timedelta object representing the local time offset from UTC at the moment"
if epoch_time == None:
epoch_time = time()
return datetime.fromtimestamp(epoch_time) - datetime.utcfromtimestamp(epoch_time)