diff --git a/pandas/tests/test_series.py b/pandas/tests/test_series.py index 22f8aee1e0a4e..055ba66f9f782 100644 --- a/pandas/tests/test_series.py +++ b/pandas/tests/test_series.py @@ -81,9 +81,10 @@ def test_dt_namespace_accessor(self): ok_for_base = ['year','month','day','hour','minute','second','weekofyear','week','dayofweek','weekday','dayofyear','quarter','freq','days_in_month','daysinmonth'] ok_for_period = ok_for_base + ['qyear'] + ok_for_period_methods = ['strftime'] ok_for_dt = ok_for_base + ['date','time','microsecond','nanosecond', 'is_month_start', 'is_month_end', 'is_quarter_start', 'is_quarter_end', 'is_year_start', 'is_year_end', 'tz'] - ok_for_dt_methods = ['to_period','to_pydatetime','tz_localize','tz_convert', 'normalize'] + ok_for_dt_methods = ['to_period','to_pydatetime','tz_localize','tz_convert', 'normalize', 'strftime'] ok_for_td = ['days','seconds','microseconds','nanoseconds'] ok_for_td_methods = ['components','to_pytimedelta'] @@ -109,13 +110,12 @@ def compare(s, name): Series(date_range('20130101',periods=5,freq='s')), Series(date_range('20130101 00:00:00',periods=5,freq='ms'))]: for prop in ok_for_dt: - # we test freq below if prop != 'freq': compare(s, prop) for prop in ok_for_dt_methods: - getattr(s.dt,prop) + getattr(s.dt, prop) result = s.dt.to_pydatetime() self.assertIsInstance(result,np.ndarray) @@ -140,13 +140,12 @@ def compare(s, name): Series(timedelta_range('1 day 01:23:45',periods=5,freq='s')), Series(timedelta_range('2 days 01:23:45.012345',periods=5,freq='ms'))]: for prop in ok_for_td: - # we test freq below if prop != 'freq': compare(s, prop) for prop in ok_for_td_methods: - getattr(s.dt,prop) + getattr(s.dt, prop) result = s.dt.components self.assertIsInstance(result,DataFrame) @@ -169,13 +168,14 @@ def compare(s, name): # periodindex for s in [Series(period_range('20130101',periods=5,freq='D'))]: - for prop in ok_for_period: - # we test freq below if prop != 'freq': compare(s, prop) + for prop in ok_for_period_methods: + getattr(s.dt, prop) + freq_result = s.dt.freq self.assertEqual(freq_result, PeriodIndex(s.values).freq) @@ -190,7 +190,7 @@ def get_dir(s): s = Series(period_range('20130101',periods=5,freq='D').asobject) results = get_dir(s) - tm.assert_almost_equal(results,list(sorted(set(ok_for_period)))) + tm.assert_almost_equal(results, list(sorted(set(ok_for_period + ok_for_period_methods)))) # no setting allowed s = Series(date_range('20130101',periods=5,freq='D')) @@ -203,6 +203,27 @@ def f(): s.dt.hour[0] = 5 self.assertRaises(com.SettingWithCopyError, f) + def test_strftime(self): + # GH 10086 + s = Series(date_range('20130101', periods=5)) + result = s.dt.strftime('%Y/%m/%d') + expected = Series(['2013/01/01', '2013/01/02', '2013/01/03', '2013/01/04', '2013/01/05']) + tm.assert_series_equal(result, expected) + + s.iloc[0] = pd.NaT + result = s.dt.strftime('%Y/%m/%d') + expected = Series(['NaT', '2013/01/02', '2013/01/03', '2013/01/04', '2013/01/05']) + tm.assert_series_equal(result, expected) + + datetime_index = date_range('20150301', periods=5) + result = datetime_index.strftime("%Y/%m/%d") + expected = ['2015/03/01', '2015/03/02', '2015/03/03', '2015/03/04', '2015/03/05'] + self.assertEqual(result, expected) + + period_index = period_range('20150301', periods=5) + expected = ['2015/03/01', '2015/03/02', '2015/03/03', '2015/03/04', '2015/03/05'] + self.assertEqual(result, expected) + def test_valid_dt_with_missing_values(self): from datetime import date, time diff --git a/pandas/tseries/common.py b/pandas/tseries/common.py index 8e468a7701462..d2c3e5592e077 100644 --- a/pandas/tseries/common.py +++ b/pandas/tseries/common.py @@ -125,7 +125,7 @@ def to_pydatetime(self): accessors=DatetimeIndex._datetimelike_ops, typ='property') DatetimeProperties._add_delegate_accessors(delegate=DatetimeIndex, - accessors=["to_period","tz_localize","tz_convert","normalize"], + accessors=["to_period","tz_localize","tz_convert","normalize","strftime"], typ='method') class TimedeltaProperties(Properties): @@ -181,6 +181,9 @@ class PeriodProperties(Properties): PeriodProperties._add_delegate_accessors(delegate=PeriodIndex, accessors=PeriodIndex._datetimelike_ops, typ='property') +PeriodProperties._add_delegate_accessors(delegate=PeriodIndex, + accessors=["strftime"], + typ='method') class CombinedDatetimelikeProperties(DatetimeProperties, TimedeltaProperties): diff --git a/pandas/tseries/index.py b/pandas/tseries/index.py index f56b40a70d551..b009fbb715bd8 100644 --- a/pandas/tseries/index.py +++ b/pandas/tseries/index.py @@ -694,6 +694,21 @@ def astype(self, dtype): else: # pragma: no cover raise ValueError('Cannot cast DatetimeIndex to dtype %s' % dtype) + def strftime(self, date_format): + """ + Return a list of formmatted strings specified by date_format + + Parameters + ---------- + date_format : str + date format string (e.g. "%Y-%m-%d") + + Returns + ------- + a list formatted strings + """ + return self.format(date_format=date_format) + def _get_time_micros(self): utc = _utc() values = self.asi8 diff --git a/pandas/tseries/period.py b/pandas/tseries/period.py index 8b7dc90738bd0..39daa7eba1ef8 100644 --- a/pandas/tseries/period.py +++ b/pandas/tseries/period.py @@ -328,6 +328,21 @@ def astype(self, dtype): return Index(self.values, dtype) raise ValueError('Cannot cast PeriodIndex to dtype %s' % dtype) + def strftime(self, date_format): + """ + Return a list of formmatted strings specified by date_format + + Parameters + ---------- + date_format : str + date format string (e.g. "%Y-%m-%d") + + Returns + ------- + a list formatted strings + """ + return self.format(date_format=date_format) + def searchsorted(self, key, side='left'): if isinstance(key, Period): if key.freq != self.freq: