Skip to content

Commit 9ab270f

Browse files
mroeschkejreback
authored andcommitted
ENH: Support datetime.timezone objects (#25065)
1 parent 90617c6 commit 9ab270f

File tree

6 files changed

+23
-13
lines changed

6 files changed

+23
-13
lines changed

doc/source/user_guide/timeseries.rst

+11-5
Original file line numberDiff line numberDiff line change
@@ -2149,12 +2149,9 @@ Time Zone Handling
21492149
------------------
21502150

21512151
pandas provides rich support for working with timestamps in different time
2152-
zones using the ``pytz`` and ``dateutil`` libraries.
2152+
zones using the ``pytz`` and ``dateutil`` libraries or class:`datetime.timezone`
2153+
objects from the standard library.
21532154

2154-
.. note::
2155-
2156-
pandas does not yet support ``datetime.timezone`` objects from the standard
2157-
library.
21582155

21592156
Working with Time Zones
21602157
~~~~~~~~~~~~~~~~~~~~~~~
@@ -2197,6 +2194,15 @@ To return ``dateutil`` time zone objects, append ``dateutil/`` before the string
21972194
tz=dateutil.tz.tzutc())
21982195
rng_utc.tz
21992196
2197+
.. versionadded:: 0.25.0
2198+
2199+
.. ipython:: python
2200+
2201+
# datetime.timezone
2202+
rng_utc = pd.date_range('3/6/2012 00:00', periods=3, freq='D',
2203+
tz=datetime.timezone.utc)
2204+
rng_utc.tz
2205+
22002206
Note that the ``UTC`` time zone is a special case in ``dateutil`` and should be constructed explicitly
22012207
as an instance of ``dateutil.tz.tzutc``. You can also construct other time
22022208
zones objects explicitly first.

doc/source/whatsnew/v0.25.0.rst

+1
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ Other Enhancements
2828
- :meth:`DatetimeIndex.union` now supports the ``sort`` argument. The behaviour of the sort parameter matches that of :meth:`Index.union` (:issue:`24994`)
2929
- :meth:`DataFrame.rename` now supports the ``errors`` argument to raise errors when attempting to rename nonexistent keys (:issue:`13473`)
3030
- :class:`RangeIndex` has gained :attr:`~RangeIndex.start`, :attr:`~RangeIndex.stop`, and :attr:`~RangeIndex.step` attributes (:issue:`25710`)
31+
- :class:`datetime.timezone` objects are now supported as arguments to timezone methods and constructors (:issue:`25065`)
3132

3233
.. _whatsnew_0250.api_breaking:
3334

pandas/_libs/tslibs/timezones.pyx

+5-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
# -*- coding: utf-8 -*-
2+
from datetime import timezone
23

34
# dateutil compat
45
from dateutil.tz import (
@@ -23,11 +24,12 @@ from pandas._libs.tslibs.util cimport (
2324
is_string_object, is_integer_object, get_nat)
2425

2526
cdef int64_t NPY_NAT = get_nat()
27+
cdef object utc_stdlib = timezone.utc
2628

2729
# ----------------------------------------------------------------------
2830

2931
cpdef inline bint is_utc(object tz):
30-
return tz is UTC or isinstance(tz, _dateutil_tzutc)
32+
return tz is UTC or tz is utc_stdlib or isinstance(tz, _dateutil_tzutc)
3133

3234

3335
cdef inline bint is_tzlocal(object tz):
@@ -167,6 +169,8 @@ cdef inline bint is_fixed_offset(object tz):
167169
return 1
168170
else:
169171
return 0
172+
# This also implicitly accepts datetime.timezone objects which are
173+
# considered fixed
170174
return 1
171175

172176

pandas/conftest.py

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from datetime import date, time, timedelta
1+
from datetime import date, time, timedelta, timezone
22
from decimal import Decimal
33
import os
44

@@ -247,13 +247,11 @@ def writable(request):
247247

248248
@pytest.fixture(scope='module')
249249
def datetime_tz_utc():
250-
from datetime import timezone
251250
return timezone.utc
252251

253252

254253
utc_objs = ['utc', 'dateutil/UTC', utc, tzutc()]
255254
if PY3:
256-
from datetime import timezone
257255
utc_objs.append(timezone.utc)
258256

259257

@@ -366,7 +364,9 @@ def unique_nulls_fixture(request):
366364

367365
TIMEZONES = [None, 'UTC', 'US/Eastern', 'Asia/Tokyo', 'dateutil/US/Pacific',
368366
'dateutil/Asia/Singapore', tzutc(), tzlocal(), FixedOffset(300),
369-
FixedOffset(0), FixedOffset(-300)]
367+
FixedOffset(0), FixedOffset(-300), timezone.utc,
368+
timezone(timedelta(hours=1)),
369+
timezone(timedelta(hours=-1), name='foo')]
370370

371371

372372
@td.parametrize_fixture_doc(str(TIMEZONES))

pandas/tests/indexes/datetimes/test_construction.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ def test_construction_with_alt_tz_localize(self, kwargs, tz_aware_fixture):
119119
i = pd.date_range('20130101', periods=5, freq='H', tz=tz)
120120
kwargs = {key: attrgetter(val)(i) for key, val in kwargs.items()}
121121

122-
if str(tz) in ('UTC', 'tzutc()'):
122+
if str(tz) in ('UTC', 'tzutc()', 'UTC+00:00'):
123123
warn = None
124124
else:
125125
warn = FutureWarning

pandas/tests/indexes/test_base.py

+1-2
Original file line numberDiff line numberDiff line change
@@ -416,9 +416,8 @@ def test_constructor_dtypes_datetime(self, tz_naive_fixture, attr, utc,
416416
# TODO(GH-24559): Remove the sys.modules and warnings
417417
# not sure what this is from. It's Py2 only.
418418
modules = [sys.modules['pandas.core.indexes.base']]
419-
420419
if (tz_naive_fixture and attr == "asi8" and
421-
str(tz_naive_fixture) not in ('UTC', 'tzutc()')):
420+
str(tz_naive_fixture) not in ('UTC', 'tzutc()', 'UTC+00:00')):
422421
ex_warn = FutureWarning
423422
else:
424423
ex_warn = None

0 commit comments

Comments
 (0)