Skip to content

Commit f7bed5d

Browse files
jschendelproost
authored andcommitted
BUG: Fix DatetimeIndex.strftime with NaT present (pandas-dev#29583)
1 parent 36cfe71 commit f7bed5d

File tree

4 files changed

+36
-5
lines changed

4 files changed

+36
-5
lines changed

doc/source/whatsnew/v1.0.0.rst

+1-1
Original file line numberDiff line numberDiff line change
@@ -314,7 +314,7 @@ Datetimelike
314314
- Bug in :func:`pandas.core.groupby.generic.SeriesGroupBy.apply` raising ``ValueError`` when a column in the original DataFrame is a datetime and the column labels are not standard integers (:issue:`28247`)
315315
- Bug in :func:`pandas._config.localization.get_locales` where the ``locales -a`` encodes the locales list as windows-1252 (:issue:`23638`, :issue:`24760`, :issue:`27368`)
316316
- Bug in :meth:`Series.var` failing to raise ``TypeError`` when called with ``timedelta64[ns]`` dtype (:issue:`28289`)
317-
-
317+
- Bug in :meth:`DatetimeIndex.strftime` and :meth:`Series.dt.strftime` where ``NaT`` was converted to the string ``'NaT'`` instead of ``np.nan`` (:issue:`29578`)
318318

319319
Timedelta
320320
^^^^^^^^^

pandas/core/arrays/datetimelike.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,8 @@ def strftime(self, date_format):
179179
'March 10, 2018, 09:00:02 AM'],
180180
dtype='object')
181181
"""
182-
return self._format_native_types(date_format=date_format).astype(object)
182+
result = self._format_native_types(date_format=date_format, na_rep=np.nan)
183+
return result.astype(object)
183184

184185

185186
class TimelikeOps:

pandas/tests/arrays/test_datetimelike.py

+18-2
Original file line numberDiff line numberDiff line change
@@ -473,7 +473,15 @@ def test_strftime(self, datetime_index):
473473
arr = DatetimeArray(datetime_index)
474474

475475
result = arr.strftime("%Y %b")
476-
expected = np.array(datetime_index.strftime("%Y %b"))
476+
expected = np.array([ts.strftime("%Y %b") for ts in arr], dtype=object)
477+
tm.assert_numpy_array_equal(result, expected)
478+
479+
def test_strftime_nat(self):
480+
# GH 29578
481+
arr = DatetimeArray(DatetimeIndex(["2019-01-01", pd.NaT]))
482+
483+
result = arr.strftime("%Y-%m-%d")
484+
expected = np.array(["2019-01-01", np.nan], dtype=object)
477485
tm.assert_numpy_array_equal(result, expected)
478486

479487

@@ -679,7 +687,15 @@ def test_strftime(self, period_index):
679687
arr = PeriodArray(period_index)
680688

681689
result = arr.strftime("%Y")
682-
expected = np.array(period_index.strftime("%Y"))
690+
expected = np.array([per.strftime("%Y") for per in arr], dtype=object)
691+
tm.assert_numpy_array_equal(result, expected)
692+
693+
def test_strftime_nat(self):
694+
# GH 29578
695+
arr = PeriodArray(PeriodIndex(["2019-01-01", pd.NaT], dtype="period[D]"))
696+
697+
result = arr.strftime("%Y-%m-%d")
698+
expected = np.array(["2019-01-01", np.nan], dtype=object)
683699
tm.assert_numpy_array_equal(result, expected)
684700

685701

pandas/tests/series/test_datetime_values.py

+15-1
Original file line numberDiff line numberDiff line change
@@ -504,7 +504,7 @@ def test_strftime(self):
504504
s.iloc[0] = pd.NaT
505505
result = s.dt.strftime("%Y/%m/%d")
506506
expected = Series(
507-
["NaT", "2013/01/02", "2013/01/03", "2013/01/04", "2013/01/05"]
507+
[np.nan, "2013/01/02", "2013/01/03", "2013/01/04", "2013/01/05"]
508508
)
509509
tm.assert_series_equal(result, expected)
510510

@@ -554,6 +554,20 @@ def test_strftime(self):
554554
)
555555
tm.assert_series_equal(result, expected)
556556

557+
@pytest.mark.parametrize(
558+
"data",
559+
[
560+
DatetimeIndex(["2019-01-01", pd.NaT]),
561+
PeriodIndex(["2019-01-01", pd.NaT], dtype="period[D]"),
562+
],
563+
)
564+
def test_strftime_nat(self, data):
565+
# GH 29578
566+
s = Series(data)
567+
result = s.dt.strftime("%Y-%m-%d")
568+
expected = Series(["2019-01-01", np.nan])
569+
tm.assert_series_equal(result, expected)
570+
557571
def test_valid_dt_with_missing_values(self):
558572

559573
from datetime import date, time

0 commit comments

Comments
 (0)