2014-07-10 20 views
8

我想爲本地日期時間對象添加或減去星期(或幾天或幾個月或幾年)。問題在於,由於夏令時區的原因,天真的做法會導致1小時的班次。如何添加關於夏令時時區的每週timedeltours

2014-03-27 12:00正好在從冬季轉到夏季之前。如果我在本地化時區歐洲/柏林添加一個星期的timedelta,結果將會是2014-04-03 13:00。我想有一天的同一小時,2014-04-03 12:00。我發現一個解決方案:

from datetime import datetime, timedelta 
import pytz 
my_tz = pytz.timezone("Europe/Berlin") 

def add_relativedelta(date, delta): 
    """ 
    Adds the given timedelta to the given date. Shifts in timezone offsets 
    will be removed. 
    """ 
    tz = date.tzinfo 
    result = tz.normalize(date + delta) 
    if result.utcoffset() != date.utcoffset(): 
     result = tz.normalize(date.utcoffset() - result.utcoffset() + result) 
    return result 

date = my_tz.localize(datetime(year=2014, month=3, day=27, hour=12, minute=0)) 
print """{} Original localized date (winter time) 
{} One week later (summer time) 
{} Date one week later preserving hour of day (summer time)""".format(date, 
        my_tz.normalize(date + timedelta(days=7)), 
        add_relativedelta(date, timedelta(days=7))) 


2014-03-27 12:00:00+01:00 Original localized date (winter time) 
2014-04-03 13:00:00+02:00 One week later (summer time) 
2014-04-03 12:00:00+02:00 Date one week later preserving hour of day (summer time) 

我想知道是否有更通用/更好的解決方案。有沒有可以解決這個問題的圖書館?這似乎是一個相當普遍的問題。

回答

14

timedelta(days=7)意味着7天,如在7*24小時 - 而不是「太陽日」。 如果您將7天添加到支持時區的日期時間,您將獲得7天后的日期時間 - 與時區中代表的日期時間無關。

看來你真正想要的是將delta應用到你指定的時間,忽略了時區的細節。注意區別:

In [13]: print my_tz.normalize(my_tz.localize(dt) + delta) 
2014-04-03 13:00:00+02:00 

In [14]: print my_tz.normalize(my_tz.localize(dt + delta)) 
2014-04-03 12:00:00+02:00 

因此,如果可能的話,應用deltas到本地化之前的日期時間。