I want to add or subtract weeks (or days or month or years) to localized datetime objects. The problem is, that the naive approach will result in 1 hour shifts due to daylight saving timezones.
2014-03-27 12:00 is right before the switch from winter to summer time. If I add a timedelta of one week to this date localized in timezone Europe/Berlin for example, the result will be 2014-04-03 13:00. I would like to have the same hour of day, 2014-04-03 12:00. I found a solution:
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)
I was wondering if there is more generic/better solution. Are there any libraries that could solve this? This seems to be a pretty common issue.