python 使用 pytz 进行不正确的时区转换

发布于 2024-10-18 11:06:42 字数 1462 浏览 4 评论 0原文

我用 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' 但巴西的 DST 于 2 月 20 日结束,正确答案应该是'2011-02-20 09:00:00 EST-0500'。

通过一些实验,我发现根据 pytz,巴西的夏令时于 2 月 27 日结束,这是不正确的。

pytz 是否包含错误的数据或者我遗漏了什么。任何帮助或意见将不胜感激。

I wrote the following script in python to convert datetime from any given timezone to 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  

When I call this method with
convert2EST('20110220', '11:00:00', 'America/Sao_Paulo')

output is '2011-02-20 08:00:00 EST-0500' but DST in Brazil ended on 20th Feb and correct answer should be '2011-02-20 09:00:00 EST-0500'.

From some experimentation I figured out that according to pytz Brazil's DST ends on 27th Feb which is incorrect.

Does pytz contains wrong data or I am missing something. Any help or comments will be much appreciated.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

凉薄对峙 2024-10-25 11:06:42

首先稍微不那么疯狂的实现:

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 也能得到正确答案的原因,它使用了我的操作系统中的(更新的)数据。

Firstly slightly less insane implementation:

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)

Now, we try to call it:

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

As we see, we get the correct answer.

Update: I got it!

Brazil changed it's daylight savings in 2008. It's unclear what it was before that, but likely your data is old.

This is probably not pytz fault as pytz is able to use your operating systems database. You probably need to update your operating system. This is (I guess) the reason I got the correct answer even with a pytz from 2005, it used the (updated) data from my OS.

白日梦 2024-10-25 11:06:42

看来你已经回答了你自己的问题。如果 pytz 说巴西 DST 于 2 月 27 日结束,那么这是错误的。巴西的夏令时结束于 二月的第三个星期日,除非该星期日在狂欢节期间;今年没有,所以 DST 没有延迟。

也就是说,您似乎不必要地滚动自己的转换器。您应该查看 time 模块,它可以简化之间的转换GMT 和当地时间等。

Seems like you have answered your own question. If pytz says DST ends on 27 Feb in Brazil, it's wrong. DST in Brazil ends on the third Sunday of February, unless that Sunday falls during Carnival; it does not this year, so DST is not delayed.

That said, you seem to be rolling your own converter unnecessarily. You should look at the time module, which eases conversions between gmt and local time, among other things.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文