Skip to content

Commit e8c1af9

Browse files
mroeschkePingviinituutti
authored andcommitted
API: Ensure DatetimeTZDtype standardizes pytz timezones (pandas-dev#25254)
* API: Ensure DatetimeTZDtype standardizes pytz timezones * Add whatsnew
1 parent bc6b168 commit e8c1af9

File tree

4 files changed

+36
-1
lines changed

4 files changed

+36
-1
lines changed

doc/source/user_guide/timeseries.rst

+24
Original file line numberDiff line numberDiff line change
@@ -321,6 +321,15 @@ which can be specified. These are computed from the starting point specified by
321321
pd.to_datetime([1349720105100, 1349720105200, 1349720105300,
322322
1349720105400, 1349720105500], unit='ms')
323323
324+
Constructing a :class:`Timestamp` or :class:`DatetimeIndex` with an epoch timestamp
325+
with the ``tz`` argument specified will localize the epoch timestamps to UTC
326+
first then convert the result to the specified time zone.
327+
328+
.. ipython:: python
329+
330+
pd.Timestamp(1262347200000000000, tz='US/Pacific')
331+
pd.DatetimeIndex([1262347200000000000], tz='US/Pacific')
332+
324333
.. note::
325334

326335
Epoch times will be rounded to the nearest nanosecond.
@@ -2205,6 +2214,21 @@ you can use the ``tz_convert`` method.
22052214
22062215
rng_pytz.tz_convert('US/Eastern')
22072216
2217+
.. note::
2218+
2219+
When using ``pytz`` time zones, :class:`DatetimeIndex` will construct a different
2220+
time zone object than a :class:`Timestamp` for the same time zone input. A :class:`DatetimeIndex`
2221+
can hold a collection of :class:`Timestamp` objects that may have different UTC offsets and cannot be
2222+
succinctly represented by one ``pytz`` time zone instance while one :class:`Timestamp`
2223+
represents one point in time with a specific UTC offset.
2224+
2225+
.. ipython:: python
2226+
2227+
dti = pd.date_range('2019-01-01', periods=3, freq='D', tz='US/Pacific')
2228+
dti.tz
2229+
ts = pd.Timestamp('2019-01-01', tz='US/Pacific')
2230+
ts.tz
2231+
22082232
.. warning::
22092233

22102234
Be wary of conversions between libraries. For some time zones, ``pytz`` and ``dateutil`` have different

doc/source/whatsnew/v0.25.0.rst

+1-1
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ Backwards incompatible API changes
3333
Other API Changes
3434
^^^^^^^^^^^^^^^^^
3535

36-
-
36+
- :class:`DatetimeTZDtype` will now standardize pytz timezones to a common timezone instance (:issue:`24713`)
3737
-
3838
-
3939

pandas/core/dtypes/dtypes.py

+1
Original file line numberDiff line numberDiff line change
@@ -639,6 +639,7 @@ def __init__(self, unit="ns", tz=None):
639639

640640
if tz:
641641
tz = timezones.maybe_get_tz(tz)
642+
tz = timezones.tz_standardize(tz)
642643
elif tz is not None:
643644
raise pytz.UnknownTimeZoneError(tz)
644645
elif tz is None:

pandas/tests/dtypes/test_dtypes.py

+10
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
import numpy as np
55
import pytest
6+
import pytz
67

78
from pandas.core.dtypes.common import (
89
is_bool_dtype, is_categorical, is_categorical_dtype,
@@ -302,6 +303,15 @@ def test_empty(self):
302303
with pytest.raises(TypeError, match="A 'tz' is required."):
303304
DatetimeTZDtype()
304305

306+
def test_tz_standardize(self):
307+
# GH 24713
308+
tz = pytz.timezone('US/Eastern')
309+
dr = date_range('2013-01-01', periods=3, tz='US/Eastern')
310+
dtype = DatetimeTZDtype('ns', dr.tz)
311+
assert dtype.tz == tz
312+
dtype = DatetimeTZDtype('ns', dr[0].tz)
313+
assert dtype.tz == tz
314+
305315

306316
class TestPeriodDtype(Base):
307317

0 commit comments

Comments
 (0)