Skip to content

Commit ce4d3aa

Browse files
committed
Use zoneinfo as a base Timezone implementation
1 parent 3bceca6 commit ce4d3aa

22 files changed

+157
-1161
lines changed

pendulum/_extensions/_helpers.c

+7-1
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,13 @@ char *_get_tz_name(PyObject *dt)
165165

166166
if (tzinfo != Py_None)
167167
{
168-
if (PyObject_HasAttrString(tzinfo, "name"))
168+
if (PyObject_HasAttrString(tzinfo, "key"))
169+
{
170+
// zoneinfo timezone
171+
tz = (char *)PyUnicode_AsUTF8(
172+
PyObject_GetAttrString(tzinfo, "name"));
173+
}
174+
else if (PyObject_HasAttrString(tzinfo, "name"))
169175
{
170176
// Pendulum timezone
171177
tz = (char *)PyUnicode_AsUTF8(

pendulum/_extensions/helpers.py

+8-2
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,7 @@ def precise_diff(
197197
198198
:rtype: PreciseDiff
199199
"""
200+
print("DT", d1, d2)
200201
sign = 1
201202

202203
if d1 == d2:
@@ -234,14 +235,19 @@ def precise_diff(
234235
# Trying to figure out the timezone names
235236
# If we can't find them, we assume different timezones
236237
if tzinfo1 and tzinfo2:
237-
if hasattr(tzinfo1, "name"):
238+
if hasattr(tzinfo1, "key"):
239+
# zoneinfo timezone
240+
tz1 = tzinfo1.key
241+
elif hasattr(tzinfo1, "name"):
238242
# Pendulum timezone
239243
tz1 = tzinfo1.name
240244
elif hasattr(tzinfo1, "zone"):
241245
# pytz timezone
242246
tz1 = tzinfo1.zone
243247

244-
if hasattr(tzinfo2, "name"):
248+
if hasattr(tzinfo2, "key"):
249+
tz2 = tzinfo2.key
250+
elif hasattr(tzinfo2, "name"):
245251
tz2 = tzinfo2.name
246252
elif hasattr(tzinfo2, "zone"):
247253
tz2 = tzinfo2.zone

pendulum/tz/__init__.py

+16-10
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
1+
import os
2+
13
from typing import Tuple
24
from typing import Union
35

4-
import pytzdata
6+
import tzdata
57

68
from .local_timezone import get_local_timezone
79
from .local_timezone import set_local_timezone
@@ -15,13 +17,23 @@
1517
POST_TRANSITION = "post"
1618
TRANSITION_ERROR = "error"
1719

18-
timezones = pytzdata.timezones # type: Tuple[str, ...]
20+
_timezones = None
1921

2022

2123
_tz_cache = {}
2224

2325

24-
def timezone(name, extended=True): # type: (Union[str, int], bool) -> _Timezone
26+
def timezones():
27+
global _timezones
28+
29+
if _timezones is None:
30+
with open(os.path.join(os.path.dirname(tzdata.__file__), "zones")) as f:
31+
_timezones = tuple(tz.strip() for tz in f.readlines())
32+
33+
return _timezones
34+
35+
36+
def timezone(name: str) -> _Timezone:
2537
"""
2638
Return a Timezone instance given its name.
2739
"""
@@ -31,13 +43,7 @@ def timezone(name, extended=True): # type: (Union[str, int], bool) -> _Timezone
3143
if name.lower() == "utc":
3244
return UTC
3345

34-
if name in _tz_cache:
35-
return _tz_cache[name]
36-
37-
tz = _Timezone(name, extended=extended)
38-
_tz_cache[name] = tz
39-
40-
return tz
46+
return _Timezone(name)
4147

4248

4349
def fixed_timezone(offset): # type: (int) -> _FixedTimezone

pendulum/tz/exceptions.py

+5
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,11 @@ class TimezoneError(ValueError):
33
pass
44

55

6+
class InvalidTimezone(TimezoneError):
7+
8+
pass
9+
10+
611
class NonExistingTime(TimezoneError):
712

813
message = "The datetime {} does not exist."

pendulum/tz/local_timezone.py

+4-3
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,10 @@
77
from typing import Optional
88
from typing import Union
99

10+
from pendulum.utils._compat import zoneinfo
11+
1012
from .timezone import Timezone
1113
from .timezone import TimezoneFile
12-
from .zoneinfo.exceptions import InvalidTimezone
1314

1415

1516
try:
@@ -212,7 +213,7 @@ def _get_unix_timezone(_root="/"): # type: (str) -> Timezone
212213

213214
try:
214215
return Timezone(os.path.join(*tzpath))
215-
except InvalidTimezone:
216+
except zoneinfo.ZoneInfoNotFoundError:
216217
pass
217218

218219
# systemd distributions use symlinks that include the zone name,
@@ -227,7 +228,7 @@ def _get_unix_timezone(_root="/"): # type: (str) -> Timezone
227228
tzpath.insert(0, parts.pop(0))
228229
try:
229230
return Timezone(os.path.join(*tzpath))
230-
except InvalidTimezone:
231+
except zoneinfo.ZoneInfoNotFoundError:
231232
pass
232233

233234
# No explicit setting existed. Use localtime

0 commit comments

Comments
 (0)