使用pytz进行python时区转换错误

2 投票
2 回答
3195 浏览
提问于 2025-04-16 12:21

我写了一个Python脚本,用来把任何时区的时间转换成东部标准时间(EST)。

from datetime import datetime, timedelta  
from pytz import timezone  
import pytz  
utc = pytz.utc  

# Converts char representation of int to numeric representation '121'->121, '-1729'->-1729 
def toInt(ch):  
    ret = 0  
    minus = False  
    if ch[0] == '-':  
        ch = ch[1:]  
        minus = True  
    for c in ch:  
        ret = ret*10 + ord(c) - 48  
    if minus:  
        ret *= -1  
    return ret  

# Converts given datetime in tzone to EST. dt = 'yyyymmdd' and tm = 'hh:mm:ss' 
def convert2EST(dt, tm, tzone): 
    y = toInt(dt[0:4]) 
    m = toInt(dt[4:6]) 
    d = toInt(dt[6:8]) 
    hh = toInt(tm[0:2]) 
    mm = toInt(tm[3:5]) 
    ss = toInt(tm[6:8])

    # EST timezone and given timezone 
    est_tz = timezone('US/Eastern') 
    given_tz = timezone(tzone)

    fmt = '%Y-%m-%d %H:%M:%S %Z%z'

    # Initialize given datetime and convert it to local/given timezone 
    local = datetime(y, m, d, hh, mm, ss) 
    local_dt = given_tz.localize(local)


    est_dt = est_tz.normalize(local_dt.astimezone(est_tz)) 
    dt = est_dt.strftime(fmt) 
    print dt 
    return dt  

当我用这个方法调用 convert2EST('20110220', '11:00:00', 'America/Sao_Paulo')

输出结果是 '2011-02-20 08:00:00 EST-0500',但是巴西的夏令时在2月20日结束,所以正确的答案应该是 '2011-02-20 09:00:00 EST-0500'。

经过一些实验,我发现根据pytz库,巴西的夏令时在2月27日结束,这个信息是错误的。

是pytz的数据有问题,还是我哪里搞错了呢?任何帮助或评论都非常感谢。

2 个回答

2

看起来你自己已经找到了答案。如果pytz说巴西的夏令时在2月27日结束,那就是错的。巴西的夏令时在每年2月的第三个星期天结束,除非那天正好是狂欢节;而今年的狂欢节不在这个星期天,所以夏令时不会延迟。

话说回来,你似乎在不必要地自己做转换器。你应该看看time模块,它可以帮助你更轻松地在格林威治时间和当地时间之间转换,还有其他很多功能。

8

首先,这里有一个稍微简单一点的实现:

import datetime
import pytz

EST = pytz.timezone('US/Eastern')

def convert2EST(date, time, tzone):
    dt = datetime.datetime.strptime(date+time, '%Y%m%d%H:%M:%S')
    tz = pytz.timezone(tzone)
    dt = tz.localize(dt)
    return dt.astimezone(EST)

现在,我们试着调用它:

>>> print convert2EST('20110220', '11:00:00', 'America/Sao_Paulo')
2011-02-20 09:00:00-05:00

如我们所见,我们得到了正确的答案。

更新:我明白了!

巴西在2008年改变了夏令时的规定。在那之前是什么情况不太清楚,但很可能你的数据是旧的。

这可能不是pytz的问题,因为pytz可以使用你操作系统的数据库。你可能需要更新你的操作系统。我猜这就是为什么即使使用的是2005年的pytz,我仍然能得到正确答案的原因,因为它使用了我操作系统中(更新过的)数据。

撰写回答