开发者

python incorrect timezone conversion using pytz

开发者 https://www.devze.com 2023-02-12 14:21 出处:网络
I wrote the following script in python to convert datetime from any given timezone to EST. from datetime import datetime, timedelta

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:]  开发者_JS百科
        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.


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.


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.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号