Skip to content

Commit 4b7a837

Browse files
committed
Use ZoneInfo instead of dateutil.tz.gettz
1 parent d385f1d commit 4b7a837

3 files changed

Lines changed: 34 additions & 32 deletions

File tree

‎lib/matplotlib/axis.py‎

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2506,14 +2506,15 @@ def axis_date(self, tz=None):
25062506
Parameters
25072507
----------
25082508
tz : str or `datetime.tzinfo`, default: :rc:`timezone`
2509-
The timezone used to create date labels.
2509+
The timezone used to create date labels. If a string, *tz* is passed to
2510+
`~zoneinfo.ZoneInfo`.
25102511
"""
25112512
# By providing a sample datetime instance with the desired timezone,
25122513
# the registered converter can be selected, and the "units" attribute,
25132514
# which is the timezone, can be set.
25142515
if isinstance(tz, str):
2515-
import dateutil.tz
2516-
tz = dateutil.tz.gettz(tz)
2516+
import zoneinfo
2517+
tz = zoneinfo.ZoneInfo(tz)
25172518
self.update_units(datetime.datetime(2009, 1, 1, 0, 0, 0, 0, tz))
25182519

25192520
def get_tick_space(self):

‎lib/matplotlib/dates.py‎

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
"""
22
Matplotlib provides sophisticated date plotting capabilities, standing on the
3-
shoulders of python :mod:`datetime` and the add-on module dateutil_.
3+
shoulders of python :mod:`datetime`, :mod:`zoneinfo`, and the add-on module dateutil_.
44
55
By default, Matplotlib uses the units machinery described in
66
`~matplotlib.units` to convert `datetime.datetime`, and `numpy.datetime64`
@@ -87,7 +87,7 @@
8787
string. If you want to use a different timezone, pass the *tz* keyword
8888
argument of `num2date` to any date tick locators or formatters you create. This
8989
can be either a `datetime.tzinfo` instance or a string with the timezone name
90-
that can be parsed by `~dateutil.tz.gettz`.
90+
that can be parsed by `~zoneinfo.ZoneInfo`.
9191
9292
A wide range of specific and general purpose date tick locators and
9393
formatters are provided in this module. See
@@ -177,13 +177,13 @@
177177
import functools
178178
import logging
179179
import re
180+
import zoneinfo
180181

181182
from dateutil.rrule import (rrule, MO, TU, WE, TH, FR, SA, SU, YEARLY,
182183
MONTHLY, WEEKLY, DAILY, HOURLY, MINUTELY,
183184
SECONDLY)
184185
from dateutil.relativedelta import relativedelta
185186
import dateutil.parser
186-
import dateutil.tz
187187
import numpy as np
188188

189189
import matplotlib as mpl
@@ -214,10 +214,10 @@ def _get_tzinfo(tz=None):
214214
if tz == 'UTC':
215215
return UTC
216216
if isinstance(tz, str):
217-
tzinfo = dateutil.tz.gettz(tz)
217+
tzinfo = zoneinfo.ZoneInfo(tz)
218218
if tzinfo is None:
219219
raise ValueError(f"{tz} is not a valid timezone as parsed by"
220-
" dateutil.tz.gettz.")
220+
" zoneinfo.ZoneInfo.")
221221
return tzinfo
222222
if isinstance(tz, datetime.tzinfo):
223223
return tz
@@ -352,7 +352,7 @@ def _from_ordinalf(x, tz=None):
352352
dt = dt.tolist()
353353

354354
# datetime64 is always UTC:
355-
dt = dt.replace(tzinfo=dateutil.tz.gettz('UTC'))
355+
dt = dt.replace(tzinfo=datetime.timezone.utc)
356356
# but maybe we are working in a different timezone so move.
357357
dt = dt.astimezone(tz)
358358
# fix round off errors
@@ -463,7 +463,7 @@ def num2date(x, tz=None):
463463
since the epoch. See `.get_epoch` for the
464464
epoch, which can be changed by :rc:`date.epoch` or `.set_epoch`.
465465
tz : str or `~datetime.tzinfo`, default: :rc:`timezone`
466-
Timezone of *x*. If a string, *tz* is passed to `dateutil.tz`.
466+
Timezone of *x*. If a string, *tz* is passed to `~zoneinfo.ZoneInfo`.
467467
468468
Returns
469469
-------
@@ -575,7 +575,7 @@ def __init__(self, fmt, tz=None, *, usetex=None):
575575
fmt : str
576576
`~datetime.datetime.strftime` format string
577577
tz : str or `~datetime.tzinfo`, default: :rc:`timezone`
578-
Ticks timezone. If a string, *tz* is passed to `dateutil.tz`.
578+
Ticks timezone. If a string, *tz* is passed to `~zoneinfo.ZoneInfo`.
579579
usetex : bool, default: :rc:`text.usetex`
580580
To enable/disable the use of TeX's math mode for rendering the
581581
results of the formatter.
@@ -888,7 +888,7 @@ def __init__(self, locator, tz=None, defaultfmt='%Y-%m-%d', *,
888888
Locator that this axis is using.
889889
890890
tz : str or `~datetime.tzinfo`, default: :rc:`timezone`
891-
Ticks timezone. If a string, *tz* is passed to `dateutil.tz`.
891+
Ticks timezone. If a string, *tz* is passed to `~zoneinfo.ZoneInfo`.
892892
893893
defaultfmt : str
894894
The default format to use if none of the values in ``self.scaled``
@@ -1075,7 +1075,7 @@ def __init__(self, tz=None):
10751075
Parameters
10761076
----------
10771077
tz : str or `~datetime.tzinfo`, default: :rc:`timezone`
1078-
Ticks timezone. If a string, *tz* is passed to `dateutil.tz`.
1078+
Ticks timezone. If a string, *tz* is passed to `~zoneinfo.ZoneInfo`.
10791079
"""
10801080
self.tz = _get_tzinfo(tz)
10811081

@@ -1086,7 +1086,7 @@ def set_tzinfo(self, tz):
10861086
Parameters
10871087
----------
10881088
tz : str or `~datetime.tzinfo`, default: :rc:`timezone`
1089-
Ticks timezone. If a string, *tz* is passed to `dateutil.tz`.
1089+
Ticks timezone. If a string, *tz* is passed to `~zoneinfo.ZoneInfo`.
10901090
"""
10911091
self.tz = _get_tzinfo(tz)
10921092

@@ -1259,7 +1259,7 @@ def __init__(self, tz=None, minticks=5, maxticks=None,
12591259
Parameters
12601260
----------
12611261
tz : str or `~datetime.tzinfo`, default: :rc:`timezone`
1262-
Ticks timezone. If a string, *tz* is passed to `dateutil.tz`.
1262+
Ticks timezone. If a string, *tz* is passed to `~zoneinfo.ZoneInfo`.
12631263
minticks : int
12641264
The minimum number of ticks desired; controls whether ticks occur
12651265
yearly, monthly, etc.
@@ -1470,7 +1470,7 @@ def __init__(self, base=1, month=1, day=1, tz=None):
14701470
day : int, default: 1
14711471
The day on which to place the ticks.
14721472
tz : str or `~datetime.tzinfo`, default: :rc:`timezone`
1473-
Ticks timezone. If a string, *tz* is passed to `dateutil.tz`.
1473+
Ticks timezone. If a string, *tz* is passed to `~zoneinfo.ZoneInfo`.
14741474
"""
14751475
rule = rrulewrapper(YEARLY, interval=base, bymonth=month,
14761476
bymonthday=day, **self.hms0d)
@@ -1513,7 +1513,7 @@ def __init__(self, bymonth=None, bymonthday=1, interval=1, tz=None):
15131513
The interval between each iteration. For example, if
15141514
``interval=2``, mark every second occurrence.
15151515
tz : str or `~datetime.tzinfo`, default: :rc:`timezone`
1516-
Ticks timezone. If a string, *tz* is passed to `dateutil.tz`.
1516+
Ticks timezone. If a string, *tz* is passed to `~zoneinfo.ZoneInfo`.
15171517
"""
15181518
if bymonth is None:
15191519
bymonth = range(1, 13)
@@ -1545,7 +1545,7 @@ def __init__(self, byweekday=1, interval=1, tz=None):
15451545
The interval between each iteration. For example, if
15461546
``interval=2``, mark every second occurrence.
15471547
tz : str or `~datetime.tzinfo`, default: :rc:`timezone`
1548-
Ticks timezone. If a string, *tz* is passed to `dateutil.tz`.
1548+
Ticks timezone. If a string, *tz* is passed to `~zoneinfo.ZoneInfo`.
15491549
"""
15501550
rule = rrulewrapper(DAILY, byweekday=byweekday,
15511551
interval=interval, **self.hms0d)
@@ -1568,7 +1568,7 @@ def __init__(self, bymonthday=None, interval=1, tz=None):
15681568
The interval between each iteration. For example, if
15691569
``interval=2``, mark every second occurrence.
15701570
tz : str or `~datetime.tzinfo`, default: :rc:`timezone`
1571-
Ticks timezone. If a string, *tz* is passed to `dateutil.tz`.
1571+
Ticks timezone. If a string, *tz* is passed to `~zoneinfo.ZoneInfo`.
15721572
"""
15731573
if interval != int(interval) or interval < 1:
15741574
raise ValueError("interval must be an integer greater than 0")
@@ -1595,7 +1595,7 @@ def __init__(self, byhour=None, interval=1, tz=None):
15951595
The interval between each iteration. For example, if
15961596
``interval=2``, mark every second occurrence.
15971597
tz : str or `~datetime.tzinfo`, default: :rc:`timezone`
1598-
Ticks timezone. If a string, *tz* is passed to `dateutil.tz`.
1598+
Ticks timezone. If a string, *tz* is passed to `~zoneinfo.ZoneInfo`.
15991599
"""
16001600
if byhour is None:
16011601
byhour = range(24)
@@ -1620,7 +1620,7 @@ def __init__(self, byminute=None, interval=1, tz=None):
16201620
The interval between each iteration. For example, if
16211621
``interval=2``, mark every second occurrence.
16221622
tz : str or `~datetime.tzinfo`, default: :rc:`timezone`
1623-
Ticks timezone. If a string, *tz* is passed to `dateutil.tz`.
1623+
Ticks timezone. If a string, *tz* is passed to `~zoneinfo.ZoneInfo`.
16241624
"""
16251625
if byminute is None:
16261626
byminute = range(60)
@@ -1645,7 +1645,7 @@ def __init__(self, bysecond=None, interval=1, tz=None):
16451645
The interval between each iteration. For example, if
16461646
``interval=2``, mark every second occurrence.
16471647
tz : str or `~datetime.tzinfo`, default: :rc:`timezone`
1648-
Ticks timezone. If a string, *tz* is passed to `dateutil.tz`.
1648+
Ticks timezone. If a string, *tz* is passed to `~zoneinfo.ZoneInfo`.
16491649
"""
16501650
if bysecond is None:
16511651
bysecond = range(60)
@@ -1684,7 +1684,7 @@ def __init__(self, interval=1, tz=None):
16841684
The interval between each iteration. For example, if
16851685
``interval=2``, mark every second occurrence.
16861686
tz : str or `~datetime.tzinfo`, default: :rc:`timezone`
1687-
Ticks timezone. If a string, *tz* is passed to `dateutil.tz`.
1687+
Ticks timezone. If a string, *tz* is passed to `ZoneInfo`.
16881688
"""
16891689
super().__init__(tz=tz)
16901690
self._interval = interval

‎lib/matplotlib/tests/test_dates.py‎

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
import datetime
22

3-
import dateutil.tz
43
import dateutil.rrule
54
import functools
65
import numpy as np
76
import pytest
7+
import zoneinfo
88

99
from matplotlib import rc_context, style
1010
import matplotlib.dates as mdates
@@ -943,7 +943,7 @@ def _create_auto_date_locator(date1, date2, tz):
943943
]
944944
)
945945

946-
tz = dateutil.tz.gettz('Canada/Pacific')
946+
tz = zoneinfo.ZoneInfo('Canada/Pacific')
947947
d1 = datetime.datetime(1997, 1, 1, tzinfo=tz)
948948
for t_delta, expected in results:
949949
with rc_context({'_internal.classic_mode': False}):
@@ -969,7 +969,7 @@ def test_date_inverted_limit():
969969
def _test_date2num_dst(date_range, tz_convert):
970970
# Timezones
971971

972-
BRUSSELS = dateutil.tz.gettz('Europe/Brussels')
972+
BRUSSELS = zoneinfo.ZoneInfo('Europe/Brussels')
973973
UTC = mdates.UTC
974974

975975
# Create a list of timezone-aware datetime objects in UTC
@@ -1072,8 +1072,8 @@ def _test_rrulewrapper(attach_tz, get_tz):
10721072
rule = mdates.rrulewrapper(freq=dateutil.rrule.DAILY, dtstart=dtstart)
10731073

10741074
act = rule.between(dtstart, dtend)
1075-
exp = [datetime.datetime(2017, 4, 1, 13, tzinfo=dateutil.tz.tzutc()),
1076-
datetime.datetime(2017, 4, 2, 14, tzinfo=dateutil.tz.tzutc())]
1075+
exp = [datetime.datetime(2017, 4, 1, 13, tzinfo=datetime.timezone.utc),
1076+
datetime.datetime(2017, 4, 2, 14, tzinfo=datetime.timezone.utc)]
10771077

10781078
assert act == exp
10791079

@@ -1082,9 +1082,9 @@ def test_rrulewrapper():
10821082
def attach_tz(dt, zi):
10831083
return dt.replace(tzinfo=zi)
10841084

1085-
_test_rrulewrapper(attach_tz, dateutil.tz.gettz)
1085+
_test_rrulewrapper(attach_tz, zoneinfo.ZoneInfo)
10861086

1087-
SYD = dateutil.tz.gettz('Australia/Sydney')
1087+
SYD = zoneinfo.ZoneInfo('Australia/Sydney')
10881088
dtstart = datetime.datetime(2017, 4, 1, 0)
10891089
dtend = datetime.datetime(2017, 4, 4, 0)
10901090
rule = mdates.rrulewrapper(freq=dateutil.rrule.DAILY, dtstart=dtstart,
@@ -1316,7 +1316,7 @@ def test_DateLocator():
13161316
# Check default is UTC
13171317
assert locator.tz == mdates.UTC
13181318
tz_str = 'Iceland'
1319-
iceland_tz = dateutil.tz.gettz(tz_str)
1319+
iceland_tz = zoneinfo.ZoneInfo(tz_str)
13201320
# Check not Iceland
13211321
assert locator.tz != iceland_tz
13221322
# Set it to Iceland
@@ -1339,7 +1339,8 @@ def test_DateLocator():
13391339
assert locator.tz == iceland_tz
13401340

13411341
# Test invalid tz values
1342-
with pytest.raises(ValueError, match="Aiceland is not a valid timezone"):
1342+
with pytest.raises(zoneinfo.ZoneInfoNotFoundError,
1343+
match="No time zone found with key Aiceland"):
13431344
mdates.DateLocator(tz="Aiceland")
13441345
with pytest.raises(TypeError,
13451346
match="tz must be string or tzinfo subclass."):

0 commit comments

Comments
 (0)