python incorrect timezone conversion using 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:] 开发者_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.
精彩评论