1 from datetime
import tzinfo
, timedelta
, datetime
4 HOUR
= timedelta(hours
=1)
11 def utcoffset(self
, dt
):
22 # A class building tzinfo objects for fixed-offset time zones.
23 # Note that FixedOffset(0, "UTC") is a different way to build a
26 class FixedOffset(tzinfo
):
27 """Fixed offset in minutes east from UTC."""
29 def __init__(self
, offset
, name
):
30 self
.__offset
= timedelta(minutes
= offset
)
33 def utcoffset(self
, dt
):
42 # A class capturing the platform's idea of local time.
46 STDOFFSET
= timedelta(seconds
= -_time
.timezone
)
48 DSTOFFSET
= timedelta(seconds
= -_time
.altzone
)
52 DSTDIFF
= DSTOFFSET
- STDOFFSET
54 class LocalTimezone(tzinfo
):
56 def utcoffset(self
, dt
):
69 return _time
.tzname
[self
._isdst
(dt
)]
72 tt
= (dt
.year
, dt
.month
, dt
.day
,
73 dt
.hour
, dt
.minute
, dt
.second
,
75 stamp
= _time
.mktime(tt
)
76 tt
= _time
.localtime(stamp
)
77 return tt
.tm_isdst
> 0
79 Local
= LocalTimezone()
82 # A complete implementation of current DST rules for major US time zones.
84 def first_sunday_on_or_after(dt
):
85 days_to_go
= 6 - dt
.weekday()
87 dt
+= timedelta(days_to_go
)
93 # This is a simplified (i.e., wrong for a few cases) set of rules for US
94 # DST start and end times. For a complete and up-to-date set of DST rules
95 # and timezone definitions, visit the Olson Database (or try pytz):
96 # http://www.twinsun.com/tz/tz-link.htm
97 # http://sourceforge.net/projects/pytz/ (might not be up-to-date)
99 # In the US, since 2007, DST starts at 2am (standard time) on the second
100 # Sunday in March, which is the first Sunday on or after Mar 8.
101 DSTSTART_2007
= datetime(1, 3, 8, 2)
102 # and ends at 2am (DST time; 1am standard time) on the first Sunday of Nov.
103 DSTEND_2007
= datetime(1, 11, 1, 1)
104 # From 1987 to 2006, DST used to start at 2am (standard time) on the first
105 # Sunday in April and to end at 2am (DST time; 1am standard time) on the last
106 # Sunday of October, which is the first Sunday on or after Oct 25.
107 DSTSTART_1987_2006
= datetime(1, 4, 1, 2)
108 DSTEND_1987_2006
= datetime(1, 10, 25, 1)
109 # From 1967 to 1986, DST used to start at 2am (standard time) on the last
110 # Sunday in April (the one on or after April 24) and to end at 2am (DST time;
111 # 1am standard time) on the last Sunday of October, which is the first Sunday
112 # on or after Oct 25.
113 DSTSTART_1967_1986
= datetime(1, 4, 24, 2)
114 DSTEND_1967_1986
= DSTEND_1987_2006
116 class USTimeZone(tzinfo
):
118 def __init__(self
, hours
, reprname
, stdname
, dstname
):
119 self
.stdoffset
= timedelta(hours
=hours
)
120 self
.reprname
= reprname
121 self
.stdname
= stdname
122 self
.dstname
= dstname
127 def tzname(self
, dt
):
133 def utcoffset(self
, dt
):
134 return self
.stdoffset
+ self
.dst(dt
)
137 if dt
is None or dt
.tzinfo
is None:
138 # An exception may be sensible here, in one or both cases.
139 # It depends on how you want to treat them. The default
140 # fromutc() implementation (called by the default astimezone()
141 # implementation) passes a datetime with dt.tzinfo is self.
143 assert dt
.tzinfo
is self
145 # Find start and end times for US DST. For years before 1967, return
148 dststart
, dstend
= DSTSTART_2007
, DSTEND_2007
149 elif 1986 < dt
.year
< 2007:
150 dststart
, dstend
= DSTSTART_1987_2006
, DSTEND_1987_2006
151 elif 1966 < dt
.year
< 1987:
152 dststart
, dstend
= DSTSTART_1967_1986
, DSTEND_1967_1986
156 start
= first_sunday_on_or_after(dststart
.replace(year
=dt
.year
))
157 end
= first_sunday_on_or_after(dstend
.replace(year
=dt
.year
))
159 # Can't compare naive to aware objects, so strip the timezone from
161 if start
<= dt
.replace(tzinfo
=None) < end
:
166 Eastern
= USTimeZone(-5, "Eastern", "EST", "EDT")
167 Central
= USTimeZone(-6, "Central", "CST", "CDT")
168 Mountain
= USTimeZone(-7, "Mountain", "MST", "MDT")
169 Pacific
= USTimeZone(-8, "Pacific", "PST", "PDT")