I'm playing around with Google App Engine and I learned that the timezone is fixed to UTC. I want to determine the start and end time of the current day for the user's local timezone. So basically, given the current time in UTC, how do you determine the start and end time of the current day, taking into account daylight savings changeovers.
I have some clunky example code. Please note that I realise that if I'm manually specifying a date, I could specify tomorrow's date as well, but they are examples and I want to determinte it programatically. My main problem is that if I add a timedelta to a datetime with a timezone and then normalise it (like it is suggested in the pytz docs) I get a datetime which is an hour off during daylight savings switchovers.
Not mentioned in the code, but ultimately the aim is to convert these times back to UTC which is why it's important to be timezone aware.
#!/usr/bin/python
import datetime
from pytz.gae import pytz
hobart_tz = pytz.timezone('Australia/Hobart')
utc_dt = pytz.utc.localize(datetime.datetime.utcnow())
hobart_dt = utc_dt.astimezone(hobart_tz)
# create a new datetime for the start of the day and add a day to it to get tomorrow.
today_start = datetime.datetime(hobart_dt.year, hobart_dt.month, hobart_dt.day)
today_start = hobart_tz.localize(today_start)
today_end = hobart_tz.normalize(today_start + datetime.timedelta(days=1))
print 'today:', today_start
print ' next:', today_end
print
# gives:
# today: 2011-08-28 00:00:00+10:00
# next: 2011-08-29 00:00:00+10:00
# but say today is a daylight savings changeover.
# after normalisation, we are off by an hour.
dst_finish_2011 = datetime.datetime(2011, 4, 3) # this would come from hobart_dt
dst_finish_2011 = hobart_tz.localize(dst_finish_2011)
next = hobart_tz.normalize(dst_finish_2011 + datetime.timedelta(days=1))
print '2011-04-03:', dst_finish_2011
print '2011-04-04:', next # expect 2011-04-04 00:00:00+10:00
print
# gives
# 2011-04-03: 2011-04-03 00:00:00+11:00
# 2011-04-04: 2011-04-03 23:00:00+10:00 (wrong)
dst_start_2011 = datetime.datetime(2011, 10, 2) # this would come from hobart_dt
dst_start_2011 = hobart_tz.localize(dst_start_2011)
next = hobart_tz.normalize(dst_start_2011 + datetime.timedelta(days=1))
print '2011-10-02:', dst_start_2011
print '2011-10-03:', next # expect 2011-10-03 00:00:00+11:00
print
# gives
# 2011-10-02: 2011-10-02 00:00:00+10:00
# 2011-10-03: 2011-10-03 01:00:00+11:00 (wrong)
# I guess we could ignore the timezone and localise *after* ?
dst_finish_2011 = datetime.datetime(2011, 4, 3) # this would come from hobart_dt
next = dst_finish_2011 + datetime.timedelta(days=1)
# now localise
dst_finish_2011 = hobart_tz.localize(dst_finish_2011)
next = hobart_tz.localize(next)
print '2011-04-03:', dst_finish_2011
print '2011-04-04:', next # expect 2011-04-04 00:00:00+10:00
print
# gives
# 2011-04-03: 2011-04-03 00:00:00+11:00
# 2011-04-04: 2011-04-04 00:00:00+10:00
See Question&Answers more detail:
os 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…