11# datetime.py
22
3- import time as _tmod
4-
5- _DBM = (0 ,0 ,31 ,59 ,90 ,120 ,151 ,181 ,212 ,243 ,273 ,304 ,334 )
6- _DIM = (0 ,31 ,28 ,31 ,30 ,31 ,30 ,31 ,31 ,30 ,31 ,30 ,31 )
7- _TIME_SPEC = ("auto" ,"hours" ,"minutes" ,"seconds" ,"milliseconds" ,"microseconds" )
3+ import time as _t
84
95
106def _leap (y ):
117return y % 4 == 0 and (y % 100 != 0 or y % 400 == 0 )
128
139
14- def _dby (y ):
15- # year -> number of days before January 1st of year.
16- Y = y - 1
17- return Y * 365 + Y // 4 - Y // 100 + Y // 400
18-
19-
2010def _dim (y ,m ):
2111# year, month -> number of days in that month in that year.
2212if m == 2 and _leap (y ):
2313return 29
24- return _DIM [m ]
14+ return ( 0 , 31 , 28 , 31 , 30 , 31 , 30 , 31 , 31 , 30 , 31 , 30 , 31 ) [m ]
2515
2616
2717def _dbm (y ,m ):
2818# year, month -> number of days in year preceding first day of month.
29- return _DBM [m ]+ (m > 2 and _leap (y ))
30-
31-
32- def _ymd2o (y ,m ,d ):
33- # y, month, day -> ordinal, considering 01-Jan-0001 as day 1.
34- return _dby (y )+ _dbm (y ,m )+ d
19+ return (0 ,0 ,31 ,59 ,90 ,120 ,151 ,181 ,212 ,243 ,273 ,304 ,334 )[m ]+ (m > 2 and _leap (y ))
3520
3621
3722def _o2ymd (n ):
@@ -73,7 +58,7 @@ def total_seconds(self):
7358
7459@property
7560def days (self ):
76- return self ._tuple (2 )[ 0 ]
61+ return self ._tuple (1 )
7762
7863@property
7964def seconds (self ):
@@ -145,17 +130,17 @@ def __bool__(self):
145130return self ._us != 0
146131
147132def __str__ (self ):
148- return self ._format (0x40 )
133+ return self ._fmt (0x40 )
149134
150135def __hash__ (self ):
151136if not hasattr (self ,"_hash" ):
152137self ._hash = hash (self ._us )
153138return self ._hash
154139
155140def isoformat (self ):
156- return self ._format (0 )
141+ return self ._fmt (0 )
157142
158- def _format (self ,spec = 0 ):
143+ def _fmt (self ,spec = 0 ):
159144if self ._us >= 0 :
160145td = self
161146g = ""
@@ -201,8 +186,8 @@ def tuple(self):
201186
202187def _tuple (self ,n ):
203188d ,us = divmod (self ._us ,86_400_000_000 )
204- if n == 2 :
205- return d , us
189+ if n == 1 :
190+ return d
206191s ,us = divmod (us ,1_000_000 )
207192if n == 3 :
208193return d ,s ,us
@@ -241,7 +226,7 @@ def fromutc(self, dt):
241226return dt + dtdst
242227
243228def isoformat (self ,dt ):
244- return self .utcoffset (dt )._format (0x12 )
229+ return self .utcoffset (dt )._fmt (0x12 )
245230
246231
247232class timezone (tzinfo ):
@@ -276,7 +261,7 @@ def dst(self, dt):
276261def tzname (self ,dt ):
277262if self ._name :
278263return self ._name
279- return self ._offset ._format (0x22 )
264+ return self ._offset ._fmt (0x22 )
280265
281266def fromutc (self ,dt ):
282267return dt + self ._offset
@@ -287,7 +272,11 @@ def fromutc(self, dt):
287272
288273def _date (y ,m ,d ):
289274if MINYEAR <= y <= MAXYEAR and 1 <= m <= 12 and 1 <= d <= _dim (y ,m ):
290- return _ymd2o (y ,m ,d )
275+ # year -> number of days before January 1st of year.
276+ Y = y - 1
277+ _dby = Y * 365 + Y // 4 - Y // 100 + Y // 400
278+ # y, month, day -> ordinal, considering 01-Jan-0001 as day 1.
279+ return _dby + _dbm (y ,m )+ d
291280elif y == 0 and m == 0 and 1 <= d <= 3_652_059 :
292281return d
293282else :
@@ -310,11 +299,11 @@ def __init__(self, year, month, day):
310299
311300@classmethod
312301def fromtimestamp (cls ,ts ):
313- return cls (* _tmod .localtime (ts )[:3 ])
302+ return cls (* _t .localtime (ts )[:3 ])
314303
315304@classmethod
316305def today (cls ):
317- return cls (* _tmod .localtime ()[:3 ])
306+ return cls (* _t .localtime ()[:3 ])
318307
319308@classmethod
320309def fromordinal (cls ,n ):
@@ -490,7 +479,9 @@ def _iso2t(s):
490479
491480
492481def _t2iso (td ,timespec ,dt ,tz ):
493- s = td ._format (_TIME_SPEC .index (timespec ))
482+ s = td ._fmt (
483+ ("auto" ,"hours" ,"minutes" ,"seconds" ,"milliseconds" ,"microseconds" ).index (timespec )
484+ )
494485if tz is not None :
495486s += tz .isoformat (dt )
496487return s
@@ -633,18 +624,18 @@ def fromtimestamp(cls, ts, tz=None):
633624else :
634625us = 0
635626if tz is None :
636- dt = cls (* _tmod .localtime (ts )[:6 ],microsecond = us ,tzinfo = tz )
637- s = (dt - datetime (* _tmod .localtime (ts - 86400 )[:6 ]))._us // 1_000_000 - 86400
638- if s < 0 and dt == datetime (* _tmod .localtime (ts + s )[:6 ]):
627+ dt = cls (* _t .localtime (ts )[:6 ],microsecond = us ,tzinfo = tz )
628+ s = (dt - datetime (* _t .localtime (ts - 86400 )[:6 ]))._us // 1_000_000 - 86400
629+ if s < 0 and dt == datetime (* _t .localtime (ts + s )[:6 ]):
639630dt ._fd = 1
640631else :
641- dt = cls (* _tmod .gmtime (ts )[:6 ],microsecond = us ,tzinfo = tz )
632+ dt = cls (* _t .gmtime (ts )[:6 ],microsecond = us ,tzinfo = tz )
642633dt = tz .fromutc (dt )
643634return dt
644635
645636@classmethod
646637def now (cls ,tz = None ):
647- return cls .fromtimestamp (_tmod .time (),tz )
638+ return cls .fromtimestamp (_t .time (),tz )
648639
649640@classmethod
650641def fromordinal (cls ,n ):
@@ -814,7 +805,7 @@ def astimezone(self, tz=None):
814805_tz = self ._tz
815806if _tz is None :
816807ts = int (self ._mktime ())
817- os = datetime (* _tmod .localtime (ts )[:6 ])- datetime (* _tmod .gmtime (ts )[:6 ])
808+ os = datetime (* _t .localtime (ts )[:6 ])- datetime (* _t .gmtime (ts )[:6 ])
818809else :
819810os = _tz .utcoffset (self )
820811utc = self - os
@@ -823,7 +814,7 @@ def astimezone(self, tz=None):
823814
824815def _mktime (self ):
825816def local (u ):
826- return (datetime (* _tmod .localtime (u )[:6 ])- epoch )._us // 1_000_000
817+ return (datetime (* _t .localtime (u )[:6 ])- epoch )._us // 1_000_000
827818
828819epoch = datetime .EPOCH .replace (tzinfo = None )
829820t ,us = divmod ((self - epoch )._us ,1_000_000 )
@@ -863,10 +854,10 @@ def tzname(self):
863854
864855def timetuple (self ):
865856if self ._tz is None :
866- conv = _tmod .gmtime
857+ conv = _t .gmtime
867858epoch = datetime .EPOCH .replace (tzinfo = None )
868859else :
869- conv = _tmod .localtime
860+ conv = _t .localtime
870861epoch = datetime .EPOCH
871862return conv (round ((self - epoch ).total_seconds ()))
872863
@@ -909,4 +900,4 @@ def tuple(self):
909900return d + t + (self ._tz ,self ._fd )
910901
911902
912- datetime .EPOCH = datetime (* _tmod .gmtime (0 )[:6 ],tzinfo = timezone .utc )
903+ datetime .EPOCH = datetime (* _t .gmtime (0 )[:6 ],tzinfo = timezone .utc )