diff --git a/doc/source/whatsnew/v0.17.0.txt b/doc/source/whatsnew/v0.17.0.txt index 102460ff6d476..cc044bc35a707 100644 --- a/doc/source/whatsnew/v0.17.0.txt +++ b/doc/source/whatsnew/v0.17.0.txt @@ -61,3 +61,10 @@ Bug Fixes ~~~~~~~~~ - Bug in ``Categorical`` repr with ``display.width`` of ``None`` in Python 3 (:issue:`10087`) + + +- Bug in ``Timestamp``'s' ``microsecond``, ``quarter``, ``dayofyear``, ``week`` and ``daysinmonth`` properties return ``np.int`` type, not built-in ``int``. (:issue:`10050`) +- Bug in ``NaT`` raises ``AttributeError`` when accessing to ``daysinmonth``, ``dayofweek`` properties. (:issue:`10096`) + + + diff --git a/pandas/tseries/tests/test_timedeltas.py b/pandas/tseries/tests/test_timedeltas.py index 45145eb7ab7e8..ae868af60ae63 100644 --- a/pandas/tseries/tests/test_timedeltas.py +++ b/pandas/tseries/tests/test_timedeltas.py @@ -311,49 +311,64 @@ def test_fields(self): # compat to datetime.timedelta rng = to_timedelta('1 days, 10:11:12') - self.assertEqual(rng.days,1) - self.assertEqual(rng.seconds,10*3600+11*60+12) - self.assertEqual(rng.microseconds,0) - self.assertEqual(rng.nanoseconds,0) + self.assertEqual(rng.days, 1) + self.assertEqual(rng.seconds, 10*3600+11*60+12) + self.assertEqual(rng.microseconds, 0) + self.assertEqual(rng.nanoseconds, 0) self.assertRaises(AttributeError, lambda : rng.hours) self.assertRaises(AttributeError, lambda : rng.minutes) self.assertRaises(AttributeError, lambda : rng.milliseconds) + # GH 10050 + self.assertTrue(isinstance(rng.days, int)) + self.assertTrue(isinstance(rng.seconds, int)) + self.assertTrue(isinstance(rng.microseconds, int)) + self.assertTrue(isinstance(rng.nanoseconds, int)) + td = Timedelta('-1 days, 10:11:12') - self.assertEqual(abs(td),Timedelta('13:48:48')) + self.assertEqual(abs(td), Timedelta('13:48:48')) self.assertTrue(str(td) == "-1 days +10:11:12") - self.assertEqual(-td,Timedelta('0 days 13:48:48')) - self.assertEqual(-Timedelta('-1 days, 10:11:12').value,49728000000000) - self.assertEqual(Timedelta('-1 days, 10:11:12').value,-49728000000000) + self.assertEqual(-td, Timedelta('0 days 13:48:48')) + self.assertEqual(-Timedelta('-1 days, 10:11:12').value, 49728000000000) + self.assertEqual(Timedelta('-1 days, 10:11:12').value, -49728000000000) rng = to_timedelta('-1 days, 10:11:12.100123456') - self.assertEqual(rng.days,-1) - self.assertEqual(rng.seconds,10*3600+11*60+12) - self.assertEqual(rng.microseconds,100*1000+123) - self.assertEqual(rng.nanoseconds,456) + self.assertEqual(rng.days, -1) + self.assertEqual(rng.seconds, 10*3600+11*60+12) + self.assertEqual(rng.microseconds, 100*1000+123) + self.assertEqual(rng.nanoseconds, 456) self.assertRaises(AttributeError, lambda : rng.hours) self.assertRaises(AttributeError, lambda : rng.minutes) self.assertRaises(AttributeError, lambda : rng.milliseconds) # components tup = pd.to_timedelta(-1, 'us').components - self.assertEqual(tup.days,-1) - self.assertEqual(tup.hours,23) - self.assertEqual(tup.minutes,59) - self.assertEqual(tup.seconds,59) - self.assertEqual(tup.milliseconds,999) - self.assertEqual(tup.microseconds,999) - self.assertEqual(tup.nanoseconds,0) + self.assertEqual(tup.days, -1) + self.assertEqual(tup.hours, 23) + self.assertEqual(tup.minutes, 59) + self.assertEqual(tup.seconds, 59) + self.assertEqual(tup.milliseconds, 999) + self.assertEqual(tup.microseconds, 999) + self.assertEqual(tup.nanoseconds, 0) + + # GH 10050 + self.assertTrue(isinstance(tup.days, int)) + self.assertTrue(isinstance(tup.hours, int)) + self.assertTrue(isinstance(tup.minutes, int)) + self.assertTrue(isinstance(tup.seconds, int)) + self.assertTrue(isinstance(tup.milliseconds, int)) + self.assertTrue(isinstance(tup.microseconds, int)) + self.assertTrue(isinstance(tup.nanoseconds, int)) tup = Timedelta('-1 days 1 us').components - self.assertEqual(tup.days,-2) - self.assertEqual(tup.hours,23) - self.assertEqual(tup.minutes,59) - self.assertEqual(tup.seconds,59) - self.assertEqual(tup.milliseconds,999) - self.assertEqual(tup.microseconds,999) - self.assertEqual(tup.nanoseconds,0) + self.assertEqual(tup.days, -2) + self.assertEqual(tup.hours, 23) + self.assertEqual(tup.minutes, 59) + self.assertEqual(tup.seconds, 59) + self.assertEqual(tup.milliseconds, 999) + self.assertEqual(tup.microseconds, 999) + self.assertEqual(tup.nanoseconds, 0) def test_timedelta_range(self): diff --git a/pandas/tseries/tests/test_tslib.py b/pandas/tseries/tests/test_tslib.py index e452ddee9d8db..6b3dd63e6415b 100644 --- a/pandas/tseries/tests/test_tslib.py +++ b/pandas/tseries/tests/test_tslib.py @@ -369,6 +369,58 @@ def test_today(self): self.assertTrue(abs(ts_from_string_tz.tz_localize(None) - ts_from_method_tz.tz_localize(None)) < delta) + def test_fields(self): + # GH 10050 + ts = Timestamp('2015-05-10 09:06:03.000100001') + self.assertEqual(ts.year, 2015) + self.assertTrue(isinstance(ts.year, int)) + self.assertEqual(ts.month, 5) + self.assertTrue(isinstance(ts.month, int)) + self.assertEqual(ts.day, 10) + self.assertTrue(isinstance(ts.day, int)) + self.assertEqual(ts.hour, 9) + self.assertTrue(isinstance(ts.hour, int)) + self.assertEqual(ts.minute, 6) + self.assertTrue(isinstance(ts.minute, int)) + self.assertEqual(ts.second, 3) + self.assertTrue(isinstance(ts.second, int)) + self.assertRaises(AttributeError, lambda : ts.millisecond) + self.assertEqual(ts.microsecond, 100) + self.assertTrue(isinstance(ts.microsecond, int)) + self.assertEqual(ts.nanosecond, 1) + self.assertTrue(isinstance(ts.nanosecond, int)) + self.assertEqual(ts.dayofweek, 6) + self.assertTrue(isinstance(ts.dayofweek, int)) + self.assertEqual(ts.quarter, 2) + self.assertTrue(isinstance(ts.quarter, int)) + self.assertEqual(ts.dayofyear, 130) + self.assertTrue(isinstance(ts.dayofyear, int)) + self.assertEqual(ts.week, 19) + self.assertTrue(isinstance(ts.week, int)) + self.assertEqual(ts.daysinmonth, 31) + self.assertTrue(isinstance(ts.days_in_month, int)) + self.assertEqual(ts.daysinmonth, 31) + self.assertTrue(isinstance(ts.daysinmonth, int)) + + def test_nat_fields(self): + # GH 10050 + ts = Timestamp('NaT') + self.assertTrue(np.isnan(ts.year)) + self.assertTrue(np.isnan(ts.month)) + self.assertTrue(np.isnan(ts.day)) + self.assertTrue(np.isnan(ts.hour)) + self.assertTrue(np.isnan(ts.minute)) + self.assertTrue(np.isnan(ts.second)) + self.assertTrue(np.isnan(ts.microsecond)) + self.assertTrue(np.isnan(ts.nanosecond)) + self.assertTrue(np.isnan(ts.dayofweek)) + self.assertTrue(np.isnan(ts.quarter)) + self.assertTrue(np.isnan(ts.dayofyear)) + self.assertTrue(np.isnan(ts.week)) + self.assertTrue(np.isnan(ts.daysinmonth)) + self.assertTrue(np.isnan(ts.days_in_month)) + + class TestDatetimeParsingWrappers(tm.TestCase): def test_does_not_convert_mixed_integer(self): bad_date_strings = ( diff --git a/pandas/tslib.pyx b/pandas/tslib.pyx index 40dbbd7584c7a..66f14bfb0346a 100644 --- a/pandas/tslib.pyx +++ b/pandas/tslib.pyx @@ -627,7 +627,7 @@ class NaTType(_NaT): fields = ['year', 'quarter', 'month', 'day', 'hour', 'minute', 'second', 'millisecond', 'microsecond', 'nanosecond', - 'week', 'dayofyear', 'days_in_month'] + 'week', 'dayofyear', 'days_in_month', 'daysinmonth', 'dayofweek'] for field in fields: prop = property(fget=lambda self: np.nan) setattr(NaTType, field, prop) @@ -952,7 +952,7 @@ cdef class _Timestamp(datetime): cpdef _get_field(self, field): out = get_date_field(np.array([self.value], dtype=np.int64), field) - return out[0] + return int(out[0]) cpdef _get_start_end_field(self, field): month_kw = self.freq.kwds.get('startingMonth', self.freq.kwds.get('month', 12)) if self.freq else 12