Skip to content

Commit 6b31abd

Browse files
mroeschkejreback
authored andcommitted
BUG: to_datetime ignores argument combinations (#24407)
1 parent 195cbef commit 6b31abd

File tree

3 files changed

+45
-5
lines changed

3 files changed

+45
-5
lines changed

doc/source/whatsnew/v0.24.0.rst

+2
Original file line numberDiff line numberDiff line change
@@ -1318,6 +1318,7 @@ Datetimelike
13181318
- Bug in :class:`DatetimeIndex` where constructing a :class:`DatetimeIndex` from a :class:`Categorical` or :class:`CategoricalIndex` would incorrectly drop timezone information (:issue:`18664`)
13191319
- Bug in :class:`DatetimeIndex` and :class:`TimedeltaIndex` where indexing with ``Ellipsis`` would incorrectly lose the index's ``freq`` attribute (:issue:`21282`)
13201320
- Clarified error message produced when passing an incorrect ``freq`` argument to :class:`DatetimeIndex` with ``NaT`` as the first entry in the passed data (:issue:`11587`)
1321+
- Bug in :func:`to_datetime` where ``box`` and ``utc`` arguments were ignored when passing a :class:`DataFrame` or ``dict`` of unit mappings (:issue:`23760`)
13211322

13221323
Timedelta
13231324
^^^^^^^^^
@@ -1361,6 +1362,7 @@ Timezones
13611362
- Bug in :class:`DatetimeIndex` constructor where ``NaT`` and ``dateutil.tz.tzlocal`` would raise an ``OutOfBoundsDatetime`` error (:issue:`23807`)
13621363
- Bug in :meth:`DatetimeIndex.tz_localize` and :meth:`Timestamp.tz_localize` with ``dateutil.tz.tzlocal`` near a DST transition that would return an incorrectly localized datetime (:issue:`23807`)
13631364
- Bug in :class:`Timestamp` constructor where a ``dateutil.tz.tzutc`` timezone passed with a ``datetime.datetime`` argument would be converted to a ``pytz.UTC`` timezone (:issue:`23807`)
1365+
- Bug in :func:`to_datetime` where ``utc=True`` was not respected when specifying a ``unit`` and ``errors='ignore'`` (:issue:`23758`)
13641366

13651367
Offsets
13661368
^^^^^^^

pandas/core/tools/datetimes.py

+16-5
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,12 @@ def _convert_listlike_datetimes(arg, box, format, name=None, tz=None,
204204
if box:
205205
if errors == 'ignore':
206206
from pandas import Index
207-
return Index(result, name=name)
207+
result = Index(result, name=name)
208+
# GH 23758: We may still need to localize the result with tz
209+
try:
210+
return result.tz_localize(tz)
211+
except AttributeError:
212+
return result
208213

209214
return DatetimeIndex(result, tz=tz, name=name)
210215
return result
@@ -572,7 +577,7 @@ def to_datetime(arg, errors='raise', dayfirst=False, yearfirst=False,
572577
values = convert_listlike(arg._values, True, format)
573578
result = Series(values, index=arg.index, name=arg.name)
574579
elif isinstance(arg, (ABCDataFrame, compat.MutableMapping)):
575-
result = _assemble_from_unit_mappings(arg, errors=errors)
580+
result = _assemble_from_unit_mappings(arg, errors, box, tz)
576581
elif isinstance(arg, ABCIndexClass):
577582
cache_array = _maybe_cache(arg, format, cache, convert_listlike)
578583
if not cache_array.empty:
@@ -618,7 +623,7 @@ def to_datetime(arg, errors='raise', dayfirst=False, yearfirst=False,
618623
}
619624

620625

621-
def _assemble_from_unit_mappings(arg, errors):
626+
def _assemble_from_unit_mappings(arg, errors, box, tz):
622627
"""
623628
assemble the unit specified fields from the arg (DataFrame)
624629
Return a Series for actual parsing
@@ -631,6 +636,11 @@ def _assemble_from_unit_mappings(arg, errors):
631636
- If 'raise', then invalid parsing will raise an exception
632637
- If 'coerce', then invalid parsing will be set as NaT
633638
- If 'ignore', then invalid parsing will return the input
639+
box : boolean
640+
641+
- If True, return a DatetimeIndex
642+
- If False, return an array
643+
tz : None or 'utc'
634644
635645
Returns
636646
-------
@@ -683,7 +693,7 @@ def coerce(values):
683693
coerce(arg[unit_rev['month']]) * 100 +
684694
coerce(arg[unit_rev['day']]))
685695
try:
686-
values = to_datetime(values, format='%Y%m%d', errors=errors)
696+
values = to_datetime(values, format='%Y%m%d', errors=errors, utc=tz)
687697
except (TypeError, ValueError) as e:
688698
raise ValueError("cannot assemble the "
689699
"datetimes: {error}".format(error=e))
@@ -698,7 +708,8 @@ def coerce(values):
698708
except (TypeError, ValueError) as e:
699709
raise ValueError("cannot assemble the datetimes [{value}]: "
700710
"{error}".format(value=value, error=e))
701-
711+
if not box:
712+
return values.values
702713
return values
703714

704715

pandas/tests/indexes/datetimes/test_tools.py

+27
Original file line numberDiff line numberDiff line change
@@ -949,6 +949,33 @@ def test_dataframe_dtypes(self, cache):
949949
with pytest.raises(ValueError):
950950
to_datetime(df, cache=cache)
951951

952+
def test_dataframe_box_false(self):
953+
# GH 23760
954+
df = pd.DataFrame({'year': [2015, 2016],
955+
'month': [2, 3],
956+
'day': [4, 5]})
957+
result = pd.to_datetime(df, box=False)
958+
expected = np.array(['2015-02-04', '2016-03-05'],
959+
dtype='datetime64[ns]')
960+
tm.assert_numpy_array_equal(result, expected)
961+
962+
def test_dataframe_utc_true(self):
963+
# GH 23760
964+
df = pd.DataFrame({'year': [2015, 2016],
965+
'month': [2, 3],
966+
'day': [4, 5]})
967+
result = pd.to_datetime(df, utc=True)
968+
expected = pd.Series(np.array(['2015-02-04', '2016-03-05'],
969+
dtype='datetime64[ns]')).dt.tz_localize('UTC')
970+
tm.assert_series_equal(result, expected)
971+
972+
def test_to_datetime_errors_ignore_utc_true(self):
973+
# GH 23758
974+
result = pd.to_datetime([1], unit='s', box=True, utc=True,
975+
errors='ignore')
976+
expected = DatetimeIndex(['1970-01-01 00:00:01'], tz='UTC')
977+
tm.assert_index_equal(result, expected)
978+
952979

953980
class TestToDatetimeMisc(object):
954981
def test_to_datetime_barely_out_of_bounds(self):

0 commit comments

Comments
 (0)