2011-02-23 73 views
2

我在python中編寫了下面的腳本來將datetime從任何給定的時區轉換爲EST。python不正確的時區轉換使用pytz

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' , '美/聖保羅')

輸出是「2011-02-20 08:00: 00 EST-0500「,但巴西的夏令時在2月20日結束,正確答案應爲'2011-02-20 09:00:00 EST-0500'。

從一些實驗中,我發現根據pytz,巴西的夏令時在2月27日結束,這是不正確的。

是否pytz包含錯誤的數據或我缺少一些東西。任何幫助或意見將不勝感激。

+3

您應該使用內置的'int'函數將您的字符串轉換爲整數。 – sdolan

+0

和strptime轉換爲日期。 –

回答

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

+0

根據文檔,pytz使用Olson時區數據庫,而不是OS時區。這可能只是升級到最新版本的pytz的問題。 http://pytz.sourceforge.net/#latest-versions –

+0

@Mark Ransom:Unix的大多數版本,包括所有Linux版本,還有我認爲OS X *也*使用了Olson數據庫。自從我讀了pytz源文件以來有一段時間,但是我有一個模糊的內存,它在某些情況下使用OS數據庫,而不是包含在內。這幾乎是唯一的可能性,除非他使用的是8年前的pytz版本。 –

+0

你完全正確!我安裝了一個老版本的pytz並更新它解決了這個問題。謝謝Lennart – user629424

2

似乎你已經回答了你自己的問題。如果Pytz說DST於2月27日在巴西結束,那就錯了。在巴西的DST結束於third Sunday of February,除非嘉年華期間的星期天下降;它今年不會,所以DST不會延遲。

這就是說,你似乎在不必要地滾動你自己的轉換器。您應該查看time模塊,這可以簡化gmt和當地時間之間的轉換等等。