2011-08-10 64 views
2

我写了这样的代码来获得基于DST时区一个特定时期的时间:的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和时区 在此代码,但它不是我想从Python的帮助(time模块)理解:

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 

我已misundestood什么?

+1

UTC没有DST因此'gmtime(anytime).tm_isdst == 0'。 – jfs

回答

4

我测试了这个代码来获取VM的locale 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) 
+0

谢谢,这也工作正常,一些pythonic修改。我用'return(datetime.datetime.fromtimestamp(epoch) - datetime.datetime.utcfromtimestamp(epoch))替换最后一行。“/ 3600.0' – saeedgnu

+1

@ilius:应该是'.total_seconds()'而不是'.seconds ' – jfs

+1

另请注意,“UTC偏移”和“时区”是完全不同的概念。上述代码在任何给定时间都可以用于两个或更多不同语言环境时区的相同方式。 – wberry

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洛基山”时区,其中DST开始于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西欧洲大陆的”时区,其中DST开始于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 
+0

据我所知,时代是以GMT为基础的。没有? – saeedgnu

+0

我应该写什么而不是该函数? – saeedgnu

+0

哦,是的,用localtime替换gmtime使其正确(正如我为我的位置计算的那样)。谢谢 – saeedgnu

1

感谢您的帮助,除了两个方法y ou建议,我还发现一个更灵活(也许更兼容)的版本,也可能需要时区对象(或只是使用本地区域),并返回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()