1- from datetime import tzinfo , timedelta , datetime
2-
3- ZERO = timedelta (0 )
4- HOUR = timedelta (hours = 1 )
5- SECOND = timedelta (seconds = 1 )
1+ import datetime as dt
62
73# A class capturing the platform's idea of local time.
84# (May result in wrong values on historical times in
95# timezones where UTC offset and/or the DST rules had
106# changed in the past.)
117import time as _time
128
13- STDOFFSET = timedelta (seconds = - _time .timezone )
9+ ZERO = dt .timedelta (0 )
10+ HOUR = dt .timedelta (hours = 1 )
11+ SECOND = dt .timedelta (seconds = 1 )
12+
13+ STDOFFSET = dt .timedelta (seconds = - _time .timezone )
1414if _time .daylight :
15- DSTOFFSET = timedelta (seconds = - _time .altzone )
15+ DSTOFFSET = dt . timedelta (seconds = - _time .altzone )
1616else :
1717 DSTOFFSET = STDOFFSET
1818
1919DSTDIFF = DSTOFFSET - STDOFFSET
2020
21- class LocalTimezone (tzinfo ):
2221
23- def fromutc (self , dt ):
22+ class LocalTimezone (dt .tzinfo ):
23+
24+ def fromutc (self , when ):
2425 assert dt .tzinfo is self
25- stamp = (dt - datetime (1970 , 1 , 1 , tzinfo = self )) // SECOND
26+ stamp = (when - dt . datetime (1970 , 1 , 1 , tzinfo = self )) // SECOND
2627 args = _time .localtime (stamp )[:6 ]
2728 dst_diff = DSTDIFF // SECOND
2829 # Detect fold
2930 fold = (args == _time .localtime (stamp - dst_diff ))
30- return datetime (* args , microsecond = dt .microsecond ,
31- tzinfo = self , fold = fold )
31+ return dt . datetime (* args , microsecond = when .microsecond ,
32+ tzinfo = self , fold = fold )
3233
33- def utcoffset (self , dt ):
34- if self ._isdst (dt ):
34+ def utcoffset (self , when ):
35+ if self ._isdst (when ):
3536 return DSTOFFSET
3637 else :
3738 return STDOFFSET
3839
39- def dst (self , dt ):
40- if self ._isdst (dt ):
40+ def dst (self , when ):
41+ if self ._isdst (when ):
4142 return DSTDIFF
4243 else :
4344 return ZERO
4445
45- def tzname (self , dt ):
46- return _time .tzname [self ._isdst (dt )]
46+ def tzname (self , when ):
47+ return _time .tzname [self ._isdst (when )]
4748
48- def _isdst (self , dt ):
49- tt = (dt .year , dt .month , dt .day ,
50- dt .hour , dt .minute , dt .second ,
51- dt .weekday (), 0 , 0 )
49+ def _isdst (self , when ):
50+ tt = (when .year , when .month , when .day ,
51+ when .hour , when .minute , when .second ,
52+ when .weekday (), 0 , 0 )
5253 stamp = _time .mktime (tt )
5354 tt = _time .localtime (stamp )
5455 return tt .tm_isdst > 0
5556
57+
5658Local = LocalTimezone ()
5759
5860
5961# A complete implementation of current DST rules for major US time zones.
6062
61- def first_sunday_on_or_after (dt ):
62- days_to_go = 6 - dt .weekday ()
63+ def first_sunday_on_or_after (when ):
64+ days_to_go = 6 - when .weekday ()
6365 if days_to_go :
64- dt += timedelta (days_to_go )
65- return dt
66+ when += dt . timedelta (days_to_go )
67+ return when
6668
6769
6870# US DST Rules
@@ -75,21 +77,22 @@ def first_sunday_on_or_after(dt):
7577#
7678# In the US, since 2007, DST starts at 2am (standard time) on the second
7779# Sunday in March, which is the first Sunday on or after Mar 8.
78- DSTSTART_2007 = datetime (1 , 3 , 8 , 2 )
80+ DSTSTART_2007 = dt . datetime (1 , 3 , 8 , 2 )
7981# and ends at 2am (DST time) on the first Sunday of Nov.
80- DSTEND_2007 = datetime (1 , 11 , 1 , 2 )
82+ DSTEND_2007 = dt . datetime (1 , 11 , 1 , 2 )
8183# From 1987 to 2006, DST used to start at 2am (standard time) on the first
8284# Sunday in April and to end at 2am (DST time) on the last
8385# Sunday of October, which is the first Sunday on or after Oct 25.
84- DSTSTART_1987_2006 = datetime (1 , 4 , 1 , 2 )
85- DSTEND_1987_2006 = datetime (1 , 10 , 25 , 2 )
86+ DSTSTART_1987_2006 = dt . datetime (1 , 4 , 1 , 2 )
87+ DSTEND_1987_2006 = dt . datetime (1 , 10 , 25 , 2 )
8688# From 1967 to 1986, DST used to start at 2am (standard time) on the last
8789# Sunday in April (the one on or after April 24) and to end at 2am (DST time)
8890# on the last Sunday of October, which is the first Sunday
8991# on or after Oct 25.
90- DSTSTART_1967_1986 = datetime (1 , 4 , 24 , 2 )
92+ DSTSTART_1967_1986 = dt . datetime (1 , 4 , 24 , 2 )
9193DSTEND_1967_1986 = DSTEND_1987_2006
9294
95+
9396def us_dst_range (year ):
9497 # Find start and end times for US DST. For years before 1967, return
9598 # start = end for no DST.
@@ -100,63 +103,63 @@ def us_dst_range(year):
100103 elif 1966 < year < 1987 :
101104 dststart , dstend = DSTSTART_1967_1986 , DSTEND_1967_1986
102105 else :
103- return (datetime (year , 1 , 1 ), ) * 2
106+ return (dt . datetime (year , 1 , 1 ), ) * 2
104107
105108 start = first_sunday_on_or_after (dststart .replace (year = year ))
106109 end = first_sunday_on_or_after (dstend .replace (year = year ))
107110 return start , end
108111
109112
110- class USTimeZone (tzinfo ):
113+ class USTimeZone (dt . tzinfo ):
111114
112115 def __init__ (self , hours , reprname , stdname , dstname ):
113- self .stdoffset = timedelta (hours = hours )
116+ self .stdoffset = dt . timedelta (hours = hours )
114117 self .reprname = reprname
115118 self .stdname = stdname
116119 self .dstname = dstname
117120
118121 def __repr__ (self ):
119122 return self .reprname
120123
121- def tzname (self , dt ):
122- if self .dst (dt ):
124+ def tzname (self , when ):
125+ if self .dst (when ):
123126 return self .dstname
124127 else :
125128 return self .stdname
126129
127- def utcoffset (self , dt ):
128- return self .stdoffset + self .dst (dt )
130+ def utcoffset (self , when ):
131+ return self .stdoffset + self .dst (when )
129132
130- def dst (self , dt ):
131- if dt is None or dt .tzinfo is None :
133+ def dst (self , when ):
134+ if when is None or when .tzinfo is None :
132135 # An exception may be sensible here, in one or both cases.
133136 # It depends on how you want to treat them. The default
134137 # fromutc() implementation (called by the default astimezone()
135- # implementation) passes a datetime with dt .tzinfo is self.
138+ # implementation) passes a datetime with when .tzinfo is self.
136139 return ZERO
137- assert dt .tzinfo is self
138- start , end = us_dst_range (dt .year )
140+ assert when .tzinfo is self
141+ start , end = us_dst_range (when .year )
139142 # Can't compare naive to aware objects, so strip the timezone from
140- # dt first.
141- dt = dt .replace (tzinfo = None )
143+ # when first.
144+ when = when .replace (tzinfo = None )
142145 if start + HOUR <= dt < end - HOUR :
143146 # DST is in effect.
144147 return HOUR
145- if end - HOUR <= dt < end :
146- # Fold (an ambiguous hour): use dt .fold to disambiguate.
147- return ZERO if dt .fold else HOUR
148- if start <= dt < start + HOUR :
148+ if end - HOUR <= when < end :
149+ # Fold (an ambiguous hour): use when .fold to disambiguate.
150+ return ZERO if when .fold else HOUR
151+ if start <= when < start + HOUR :
149152 # Gap (a non-existent hour): reverse the fold rule.
150- return HOUR if dt .fold else ZERO
153+ return HOUR if when .fold else ZERO
151154 # DST is off.
152155 return ZERO
153156
154- def fromutc (self , dt ):
155- assert dt .tzinfo is self
156- start , end = us_dst_range (dt .year )
157+ def fromutc (self , when ):
158+ assert when .tzinfo is self
159+ start , end = us_dst_range (when .year )
157160 start = start .replace (tzinfo = self )
158161 end = end .replace (tzinfo = self )
159- std_time = dt + self .stdoffset
162+ std_time = when + self .stdoffset
160163 dst_time = std_time + HOUR
161164 if end <= dst_time < end + HOUR :
162165 # Repeated hour
0 commit comments