Skip to content

Commit

Permalink
API: Ensure DatetimeTZDtype standardizes pytz timezones (#25254)
Browse files Browse the repository at this point in the history
* API: Ensure DatetimeTZDtype standardizes pytz timezones

* Add whatsnew
  • Loading branch information
mroeschke authored and TomAugspurger committed Feb 11, 2019
1 parent 6359bbc commit 57fb83f
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 1 deletion.
24 changes: 24 additions & 0 deletions doc/source/user_guide/timeseries.rst
Original file line number Diff line number Diff line change
Expand Up @@ -321,6 +321,15 @@ which can be specified. These are computed from the starting point specified by
pd.to_datetime([1349720105100, 1349720105200, 1349720105300,
1349720105400, 1349720105500], unit='ms')
Constructing a :class:`Timestamp` or :class:`DatetimeIndex` with an epoch timestamp
with the ``tz`` argument specified will localize the epoch timestamps to UTC
first then convert the result to the specified time zone.

.. ipython:: python
pd.Timestamp(1262347200000000000, tz='US/Pacific')
pd.DatetimeIndex([1262347200000000000], tz='US/Pacific')
.. note::

Epoch times will be rounded to the nearest nanosecond.
Expand Down Expand Up @@ -2205,6 +2214,21 @@ you can use the ``tz_convert`` method.
rng_pytz.tz_convert('US/Eastern')
.. note::

When using ``pytz`` time zones, :class:`DatetimeIndex` will construct a different
time zone object than a :class:`Timestamp` for the same time zone input. A :class:`DatetimeIndex`
can hold a collection of :class:`Timestamp` objects that may have different UTC offsets and cannot be
succinctly represented by one ``pytz`` time zone instance while one :class:`Timestamp`
represents one point in time with a specific UTC offset.

.. ipython:: python
dti = pd.date_range('2019-01-01', periods=3, freq='D', tz='US/Pacific')
dti.tz
ts = pd.Timestamp('2019-01-01', tz='US/Pacific')
ts.tz
.. warning::

Be wary of conversions between libraries. For some time zones, ``pytz`` and ``dateutil`` have different
Expand Down
2 changes: 1 addition & 1 deletion doc/source/whatsnew/v0.25.0.rst
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ Backwards incompatible API changes
Other API Changes
^^^^^^^^^^^^^^^^^

-
- :class:`DatetimeTZDtype` will now standardize pytz timezones to a common timezone instance (:issue:`24713`)
-
-

Expand Down
1 change: 1 addition & 0 deletions pandas/core/dtypes/dtypes.py
Original file line number Diff line number Diff line change
Expand Up @@ -639,6 +639,7 @@ def __init__(self, unit="ns", tz=None):

if tz:
tz = timezones.maybe_get_tz(tz)
tz = timezones.tz_standardize(tz)
elif tz is not None:
raise pytz.UnknownTimeZoneError(tz)
elif tz is None:
Expand Down
10 changes: 10 additions & 0 deletions pandas/tests/dtypes/test_dtypes.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

import numpy as np
import pytest
import pytz

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

def test_tz_standardize(self):
# GH 24713
tz = pytz.timezone('US/Eastern')
dr = date_range('2013-01-01', periods=3, tz='US/Eastern')
dtype = DatetimeTZDtype('ns', dr.tz)
assert dtype.tz == tz
dtype = DatetimeTZDtype('ns', dr[0].tz)
assert dtype.tz == tz


class TestPeriodDtype(Base):

Expand Down

0 comments on commit 57fb83f

Please sign in to comment.