Skip to content

DEPS: Added tz keyword to to_datetime function, deprecates utc #17413

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion doc/source/whatsnew/v0.21.0.txt
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,6 @@ Other Enhancements
- :func:`DataFrame.items` and :func:`Series.items` is now present in both Python 2 and 3 and is lazy in all cases (:issue:`13918`, :issue:`17213`)



.. _whatsnew_0210.api_breaking:

Backwards incompatible API changes
Expand Down Expand Up @@ -328,6 +327,10 @@ Deprecations

- ``pd.options.html.border`` has been deprecated in favor of ``pd.options.display.html.border`` (:issue:`15793`).


- :func: `to_datetime` now takes ``tz`` keyword argument, ``utc`` argument is deprecated (:issue:`13712`)
Copy link
Member

@gfyoung gfyoung Sep 1, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Say something like (don't copy, make sure to format): The "utc" argument in "to_datetime" has been deprecated in favor of "tz"



.. _whatsnew_0210.prior_deprecations:

Removal of prior version deprecations/changes
Expand Down
26 changes: 20 additions & 6 deletions pandas/core/tools/datetimes.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
ABCDataFrame, ABCDateOffset)
from pandas.core.dtypes.missing import notna
from pandas.core import algorithms
from pandas.util._decorators import deprecate_kwarg

import pandas.compat as compat

Expand Down Expand Up @@ -182,9 +183,12 @@ def _guess_datetime_format_for_array(arr, **kwargs):
return _guess_datetime_format(arr[non_nan_elements[0]], **kwargs)


@deprecate_kwarg(old_arg_name='utc', new_arg_name='tz',
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

instead of doing this, simply translate utc=True to tz='UTC' in the code itself (and issue a deprecation warning). Further you will need to raise if utc=True and tz is not None, so need a bit more handling (and add a test for this).

mapping={True: 'UTC'})
def to_datetime(arg, errors='raise', dayfirst=False, yearfirst=False,
utc=None, box=True, format=None, exact=True,
unit=None, infer_datetime_format=False, origin='unix'):
box=True, format=None, exact=True,
unit=None, infer_datetime_format=False, origin='unix',
tz=None):
"""
Convert argument to datetime.

Expand Down Expand Up @@ -223,6 +227,14 @@ def to_datetime(arg, errors='raise', dayfirst=False, yearfirst=False,
utc : boolean, default None
Return UTC DatetimeIndex if True (converting any tz-aware
datetime.datetime objects as well).

.. deprecated: 0.21.0

tz : pytz.timezone or dateutil.tz.tzfile, default None
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

str is also acceptable

Define the timezone.

.. versionadded: 0.21.0

box : boolean, default True

- If True returns a DatetimeIndex
Expand Down Expand Up @@ -343,8 +355,6 @@ def to_datetime(arg, errors='raise', dayfirst=False, yearfirst=False,
"""
from pandas.core.indexes.datetimes import DatetimeIndex

tz = 'utc' if utc else None

def _convert_listlike(arg, box, format, name=None, tz=tz):

if isinstance(arg, (list, tuple)):
Expand All @@ -354,8 +364,8 @@ def _convert_listlike(arg, box, format, name=None, tz=tz):
if is_datetime64tz_dtype(arg):
if not isinstance(arg, DatetimeIndex):
return DatetimeIndex(arg, tz=tz, name=name)
if utc:
arg = arg.tz_convert(None).tz_localize('UTC')
if tz:
arg = arg.tz_convert(None).tz_localize(tz)
return arg

elif is_datetime64_ns_dtype(arg):
Expand Down Expand Up @@ -431,6 +441,10 @@ def _convert_listlike(arg, box, format, name=None, tz=tz):
result = arg

if result is None and (format is None or infer_datetime_format):
if tz == 'utc' or tz == 'UTC':
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

don't do this, see above

utc = True
else:
utc = False
result = tslib.array_to_datetime(
arg,
errors=errors,
Expand Down
17 changes: 17 additions & 0 deletions pandas/tests/indexes/datetimes/test_tools.py
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,23 @@ def test_to_datetime_utc_is_true(self):
expected = pd.DatetimeIndex(data=date_range)
tm.assert_index_equal(result, expected)

def test_to_datetime_tz_kw(self):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Make to test the utc kwarg as being deprecated too.

# See gh-13712
for tz in [None, 'US/Eastern', 'Asia/Tokyo', 'UTC']:
data = ['20140101 000000', '20140102 000000', '20140103 000000']
start = pd.Timestamp(data[0], tz=tz)
end = pd.Timestamp(data[-1], tz=tz)
date_range = pd.bdate_range(start, end)

result = pd.to_datetime(data, format='%Y%m%d %H%M%S', tz=tz)
expected = pd.DatetimeIndex(data=date_range)
tm.assert_numpy_array_equal(result.values, expected.values)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

compare index using tm.assert_index_equal

Copy link
Member

@jorisvandenbossche jorisvandenbossche Sep 2, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jreback for some context, the reason I suggested to do it like this is because assert_index_equal fails because timezone localization on single timestamp or on datetimeindex results in a slightly different tz object. This is a separate issue as the the one solved in this pr, therefore suggested this workaround which at least test this is correct (but didn't have time to open an issue, and from phone now)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we never compare like this - too easy to get wrong; if there is an issue pls show

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can't test it now, but if I remember correctly: compare pd.Timestamp('2012-01-01', tz='US/Eastern').tz with pd.to_datetime(['2012-01-01']).tz_localize('US/Eastern').tz. Both attributes are not equal


if result.tz is None:
assert expected.tz is None
else:
assert result.tz.zone == expected.tz.zone

def test_to_datetime_tz_psycopg2(self):

# xref 8260
Expand Down