Skip to content
Merged
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
1 change: 1 addition & 0 deletions doc/source/whatsnew/v3.0.0.rst
Original file line number Diff line number Diff line change
Expand Up @@ -921,6 +921,7 @@ Conversion
- Bug in :meth:`Series.astype` might modify read-only array inplace when casting to a string dtype (:issue:`57212`)
- Bug in :meth:`Series.convert_dtypes` and :meth:`DataFrame.convert_dtypes` removing timezone information for objects with :class:`ArrowDtype` (:issue:`60237`)
- Bug in :meth:`Series.reindex` not maintaining ``float32`` type when a ``reindex`` introduces a missing value (:issue:`45857`)
- Bug in :meth:`to_datetime` and :meth:`to_timedelta` with input ``None`` returning ``None`` instead of ``NaT``, inconsistent with other conversion methods (:issue:`23055`)

Strings
^^^^^^^
Expand Down
8 changes: 6 additions & 2 deletions pandas/core/generic.py
Original file line number Diff line number Diff line change
Expand Up @@ -10519,8 +10519,12 @@ def truncate(
if ax._is_all_dates:
from pandas.core.tools.datetimes import to_datetime

before = to_datetime(before)
after = to_datetime(after)
if before is not None:
# Avoid converting to NaT
before = to_datetime(before)
if after is not None:
# Avoid converting to NaT
after = to_datetime(after)

if before is not None and after is not None and before > after:
raise ValueError(f"Truncate: {after} must be after {before}")
Expand Down
5 changes: 3 additions & 2 deletions pandas/core/tools/datetimes.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
tslib,
)
from pandas._libs.tslibs import (
NaT,
OutOfBoundsDatetime,
Timedelta,
Timestamp,
Expand Down Expand Up @@ -676,7 +677,7 @@ def to_datetime(
unit: str | None = None,
origin: str = "unix",
cache: bool = True,
) -> DatetimeIndex | Series | DatetimeScalar | NaTType | None:
) -> DatetimeIndex | Series | DatetimeScalar | NaTType:
"""
Convert argument to datetime.

Expand Down Expand Up @@ -989,7 +990,7 @@ def to_datetime(
if exact is not lib.no_default and format in {"mixed", "ISO8601"}:
raise ValueError("Cannot use 'exact' when 'format' is 'mixed' or 'ISO8601'")
if arg is None:
return None
return NaT

if origin != "unix":
arg = _adjust_to_origin(arg, origin, unit)
Expand Down
2 changes: 1 addition & 1 deletion pandas/core/tools/timedeltas.py
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ def to_timedelta(
raise ValueError("errors must be one of 'raise', or 'coerce'.")

if arg is None:
return arg
return NaT
elif isinstance(arg, ABCSeries):
values = _convert_listlike(arg._values, unit=unit, errors=errors)
return arg._constructor(values, index=arg.index, name=arg.name)
Expand Down
4 changes: 4 additions & 0 deletions pandas/tests/tools/test_to_datetime.py
Original file line number Diff line number Diff line change
Expand Up @@ -531,6 +531,10 @@ def test_to_datetime_parse_timezone_keeps_name(self):


class TestToDatetime:
def test_to_datetime_none(self):
# GH#23055
assert to_datetime(None) is NaT

@pytest.mark.filterwarnings("ignore:Could not infer format")
def test_to_datetime_overflow(self):
# we should get an OutOfBoundsDatetime, NOT OverflowError
Expand Down
4 changes: 4 additions & 0 deletions pandas/tests/tools/test_to_timedelta.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,10 @@


class TestTimedeltas:
def test_to_timedelta_none(self):
# GH#23055
assert to_timedelta(None) is pd.NaT

def test_to_timedelta_dt64_raises(self):
# Passing datetime64-dtype data to TimedeltaIndex is no longer
# supported GH#29794
Expand Down
Loading