@@ -114,29 +114,40 @@ def __int__(self) -> int:
114
114
return self ._value
115
115
116
116
117
+ def _datetime_to_millis (dtm : datetime .datetime ) -> int :
118
+ """Convert datetime to milliseconds since epoch UTC."""
119
+ if dtm .utcoffset () is not None :
120
+ dtm = dtm - dtm .utcoffset () # type: ignore
121
+ return int (calendar .timegm (dtm .timetuple ()) * 1000 + dtm .microsecond // 1000 )
122
+
123
+
117
124
_MIN_UTC = datetime .datetime .min .replace (tzinfo = utc )
118
125
_MAX_UTC = datetime .datetime .max .replace (tzinfo = utc )
126
+ _MIN_UTC_MS = _datetime_to_millis (_MIN_UTC )
127
+ _MAX_UTC_MS = _datetime_to_millis (_MAX_UTC )
119
128
120
129
121
130
# Inclusive and exclusive min and max for timezones.
122
131
# Timezones are hashed by their offset, which is a timedelta
123
132
# and therefore there are more than 24 possible timezones.
124
133
@functools .lru_cache (maxsize = None )
125
134
def _min_datetime_ms (tz : datetime .timezone = datetime .timezone .utc ) -> int :
126
- try :
127
- dtm = _MIN_UTC .astimezone (tz )
128
- except OverflowError :
129
- dtm = _MIN_UTC .replace (tzinfo = tz )
130
- return _datetime_to_millis (dtm )
135
+ delta = tz .utcoffset (_MIN_UTC )
136
+ if delta is not None :
137
+ offset_millis = (delta .days * 86400 + delta .seconds ) * 1000 + delta .microseconds // 1000
138
+ else :
139
+ offset_millis = 0
140
+ return max (_MIN_UTC_MS , _MIN_UTC_MS - offset_millis )
131
141
132
142
133
143
@functools .lru_cache (maxsize = None )
134
144
def _max_datetime_ms (tz : datetime .timezone = datetime .timezone .utc ) -> int :
135
- try :
136
- dtm = _MAX_UTC .astimezone (tz )
137
- except OverflowError :
138
- dtm = _MAX_UTC .replace (tzinfo = tz )
139
- return _datetime_to_millis (dtm )
145
+ delta = tz .utcoffset (_MAX_UTC )
146
+ if delta is not None :
147
+ offset_millis = (delta .days * 86400 + delta .seconds ) * 1000 + delta .microseconds // 1000
148
+ else :
149
+ offset_millis = 0
150
+ return min (_MAX_UTC_MS , _MAX_UTC_MS - offset_millis )
140
151
141
152
142
153
def _millis_to_datetime (
@@ -174,10 +185,3 @@ def _millis_to_datetime(
174
185
return DatetimeMS (millis )
175
186
else :
176
187
raise ValueError ("datetime_conversion must be an element of DatetimeConversion" )
177
-
178
-
179
- def _datetime_to_millis (dtm : datetime .datetime ) -> int :
180
- """Convert datetime to milliseconds since epoch UTC."""
181
- if dtm .utcoffset () is not None :
182
- dtm = dtm - dtm .utcoffset () # type: ignore
183
- return int (calendar .timegm (dtm .timetuple ()) * 1000 + dtm .microsecond // 1000 )
0 commit comments