Created
August 25, 2010 23:58
-
-
Save dickbrouwer/550535 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from datetime import timedelta, datetime | |
def first_sunday_on_or_after(dt): | |
days_to_go = 6 - dt.weekday() | |
if days_to_go: | |
dt += timedelta(days_to_go) | |
return dt | |
# For a complete and up-to-date set of DST rules and timezone definitions, | |
# visit the Olson Database: http://www.twinsun.com/tz/tz-link.htm or | |
# http://sourceforge.net/projects/pytz/ | |
# In the US, since 2007, DST starts at 2am (standard time) on the second | |
# Sunday in March, which is the first Sunday on or after Mar 8. | |
DSTSTART_2007 = datetime(1, 3, 8, 2) | |
# and ends at 2am (DST time; 1am standard time) on the first Sunday of Nov. | |
DSTEND_2007 = datetime(1, 11, 1, 1) | |
# From 1987 to 2006, DST used to start at 2am (standard time) on the first | |
# Sunday in April and to end at 2am (DST time; 1am standard time) on the last | |
# Sunday of October, which is the first Sunday on or after Oct 25. | |
DSTSTART_1987_2006 = datetime(1, 4, 1, 2) | |
DSTEND_1987_2006 = datetime(1, 10, 25, 1) | |
# From 1967 to 1986, DST used to start at 2am (standard time) on the last | |
# Sunday in April (the one on or after April 24) and to end at 2am (DST time; | |
# 1am standard time) on the last Sunday of October, which is the first Sunday | |
# on or after Oct 25. | |
DSTSTART_1967_1986 = datetime(1, 4, 24, 2) | |
DSTEND_1967_1986 = DSTEND_1987_2006 | |
def dst(dt, dst): | |
if not dst: | |
return dt | |
# Find start and end times for US DST. For years before 1967, return dt | |
if 2006 < dt.year: | |
dststart, dstend = DSTSTART_2007, DSTEND_2007 | |
elif 1986 < dt.year < 2007: | |
dststart, dstend = DSTSTART_1987_2006, DSTEND_1987_2006 | |
elif 1966 < dt.year < 1987: | |
dststart, dstend = DSTSTART_1967_1986, DSTEND_1967_1986 | |
else: | |
return dt | |
start = first_sunday_on_or_after(dststart.replace(year=dt.year)) | |
end = first_sunday_on_or_after(dstend.replace(year=dt.year)) | |
if start <= dt < end: | |
return timedelta(hours=1) + dt | |
else: | |
return dt |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment