Skip to content

Commit f6c7d89

Browse files
committed
Merge pull request #10096 from sinhrks/dt_properties
BUG: Timestamp properties may return np.int
2 parents abba4a1 + e9e0003 commit f6c7d89

File tree

4 files changed

+102
-28
lines changed

4 files changed

+102
-28
lines changed

doc/source/whatsnew/v0.17.0.txt

+7
Original file line numberDiff line numberDiff line change
@@ -61,3 +61,10 @@ Bug Fixes
6161
~~~~~~~~~
6262

6363
- Bug in ``Categorical`` repr with ``display.width`` of ``None`` in Python 3 (:issue:`10087`)
64+
65+
66+
- Bug in ``Timestamp``'s' ``microsecond``, ``quarter``, ``dayofyear``, ``week`` and ``daysinmonth`` properties return ``np.int`` type, not built-in ``int``. (:issue:`10050`)
67+
- Bug in ``NaT`` raises ``AttributeError`` when accessing to ``daysinmonth``, ``dayofweek`` properties. (:issue:`10096`)
68+
69+
70+

pandas/tseries/tests/test_timedeltas.py

+41-26
Original file line numberDiff line numberDiff line change
@@ -311,49 +311,64 @@ def test_fields(self):
311311

312312
# compat to datetime.timedelta
313313
rng = to_timedelta('1 days, 10:11:12')
314-
self.assertEqual(rng.days,1)
315-
self.assertEqual(rng.seconds,10*3600+11*60+12)
316-
self.assertEqual(rng.microseconds,0)
317-
self.assertEqual(rng.nanoseconds,0)
314+
self.assertEqual(rng.days, 1)
315+
self.assertEqual(rng.seconds, 10*3600+11*60+12)
316+
self.assertEqual(rng.microseconds, 0)
317+
self.assertEqual(rng.nanoseconds, 0)
318318

319319
self.assertRaises(AttributeError, lambda : rng.hours)
320320
self.assertRaises(AttributeError, lambda : rng.minutes)
321321
self.assertRaises(AttributeError, lambda : rng.milliseconds)
322322

323+
# GH 10050
324+
self.assertTrue(isinstance(rng.days, int))
325+
self.assertTrue(isinstance(rng.seconds, int))
326+
self.assertTrue(isinstance(rng.microseconds, int))
327+
self.assertTrue(isinstance(rng.nanoseconds, int))
328+
323329
td = Timedelta('-1 days, 10:11:12')
324-
self.assertEqual(abs(td),Timedelta('13:48:48'))
330+
self.assertEqual(abs(td), Timedelta('13:48:48'))
325331
self.assertTrue(str(td) == "-1 days +10:11:12")
326-
self.assertEqual(-td,Timedelta('0 days 13:48:48'))
327-
self.assertEqual(-Timedelta('-1 days, 10:11:12').value,49728000000000)
328-
self.assertEqual(Timedelta('-1 days, 10:11:12').value,-49728000000000)
332+
self.assertEqual(-td, Timedelta('0 days 13:48:48'))
333+
self.assertEqual(-Timedelta('-1 days, 10:11:12').value, 49728000000000)
334+
self.assertEqual(Timedelta('-1 days, 10:11:12').value, -49728000000000)
329335

330336
rng = to_timedelta('-1 days, 10:11:12.100123456')
331-
self.assertEqual(rng.days,-1)
332-
self.assertEqual(rng.seconds,10*3600+11*60+12)
333-
self.assertEqual(rng.microseconds,100*1000+123)
334-
self.assertEqual(rng.nanoseconds,456)
337+
self.assertEqual(rng.days, -1)
338+
self.assertEqual(rng.seconds, 10*3600+11*60+12)
339+
self.assertEqual(rng.microseconds, 100*1000+123)
340+
self.assertEqual(rng.nanoseconds, 456)
335341
self.assertRaises(AttributeError, lambda : rng.hours)
336342
self.assertRaises(AttributeError, lambda : rng.minutes)
337343
self.assertRaises(AttributeError, lambda : rng.milliseconds)
338344

339345
# components
340346
tup = pd.to_timedelta(-1, 'us').components
341-
self.assertEqual(tup.days,-1)
342-
self.assertEqual(tup.hours,23)
343-
self.assertEqual(tup.minutes,59)
344-
self.assertEqual(tup.seconds,59)
345-
self.assertEqual(tup.milliseconds,999)
346-
self.assertEqual(tup.microseconds,999)
347-
self.assertEqual(tup.nanoseconds,0)
347+
self.assertEqual(tup.days, -1)
348+
self.assertEqual(tup.hours, 23)
349+
self.assertEqual(tup.minutes, 59)
350+
self.assertEqual(tup.seconds, 59)
351+
self.assertEqual(tup.milliseconds, 999)
352+
self.assertEqual(tup.microseconds, 999)
353+
self.assertEqual(tup.nanoseconds, 0)
354+
355+
# GH 10050
356+
self.assertTrue(isinstance(tup.days, int))
357+
self.assertTrue(isinstance(tup.hours, int))
358+
self.assertTrue(isinstance(tup.minutes, int))
359+
self.assertTrue(isinstance(tup.seconds, int))
360+
self.assertTrue(isinstance(tup.milliseconds, int))
361+
self.assertTrue(isinstance(tup.microseconds, int))
362+
self.assertTrue(isinstance(tup.nanoseconds, int))
348363

349364
tup = Timedelta('-1 days 1 us').components
350-
self.assertEqual(tup.days,-2)
351-
self.assertEqual(tup.hours,23)
352-
self.assertEqual(tup.minutes,59)
353-
self.assertEqual(tup.seconds,59)
354-
self.assertEqual(tup.milliseconds,999)
355-
self.assertEqual(tup.microseconds,999)
356-
self.assertEqual(tup.nanoseconds,0)
365+
self.assertEqual(tup.days, -2)
366+
self.assertEqual(tup.hours, 23)
367+
self.assertEqual(tup.minutes, 59)
368+
self.assertEqual(tup.seconds, 59)
369+
self.assertEqual(tup.milliseconds, 999)
370+
self.assertEqual(tup.microseconds, 999)
371+
self.assertEqual(tup.nanoseconds, 0)
357372

358373
def test_timedelta_range(self):
359374

pandas/tseries/tests/test_tslib.py

+52
Original file line numberDiff line numberDiff line change
@@ -369,6 +369,58 @@ def test_today(self):
369369
self.assertTrue(abs(ts_from_string_tz.tz_localize(None)
370370
- ts_from_method_tz.tz_localize(None)) < delta)
371371

372+
def test_fields(self):
373+
# GH 10050
374+
ts = Timestamp('2015-05-10 09:06:03.000100001')
375+
self.assertEqual(ts.year, 2015)
376+
self.assertTrue(isinstance(ts.year, int))
377+
self.assertEqual(ts.month, 5)
378+
self.assertTrue(isinstance(ts.month, int))
379+
self.assertEqual(ts.day, 10)
380+
self.assertTrue(isinstance(ts.day, int))
381+
self.assertEqual(ts.hour, 9)
382+
self.assertTrue(isinstance(ts.hour, int))
383+
self.assertEqual(ts.minute, 6)
384+
self.assertTrue(isinstance(ts.minute, int))
385+
self.assertEqual(ts.second, 3)
386+
self.assertTrue(isinstance(ts.second, int))
387+
self.assertRaises(AttributeError, lambda : ts.millisecond)
388+
self.assertEqual(ts.microsecond, 100)
389+
self.assertTrue(isinstance(ts.microsecond, int))
390+
self.assertEqual(ts.nanosecond, 1)
391+
self.assertTrue(isinstance(ts.nanosecond, int))
392+
self.assertEqual(ts.dayofweek, 6)
393+
self.assertTrue(isinstance(ts.dayofweek, int))
394+
self.assertEqual(ts.quarter, 2)
395+
self.assertTrue(isinstance(ts.quarter, int))
396+
self.assertEqual(ts.dayofyear, 130)
397+
self.assertTrue(isinstance(ts.dayofyear, int))
398+
self.assertEqual(ts.week, 19)
399+
self.assertTrue(isinstance(ts.week, int))
400+
self.assertEqual(ts.daysinmonth, 31)
401+
self.assertTrue(isinstance(ts.days_in_month, int))
402+
self.assertEqual(ts.daysinmonth, 31)
403+
self.assertTrue(isinstance(ts.daysinmonth, int))
404+
405+
def test_nat_fields(self):
406+
# GH 10050
407+
ts = Timestamp('NaT')
408+
self.assertTrue(np.isnan(ts.year))
409+
self.assertTrue(np.isnan(ts.month))
410+
self.assertTrue(np.isnan(ts.day))
411+
self.assertTrue(np.isnan(ts.hour))
412+
self.assertTrue(np.isnan(ts.minute))
413+
self.assertTrue(np.isnan(ts.second))
414+
self.assertTrue(np.isnan(ts.microsecond))
415+
self.assertTrue(np.isnan(ts.nanosecond))
416+
self.assertTrue(np.isnan(ts.dayofweek))
417+
self.assertTrue(np.isnan(ts.quarter))
418+
self.assertTrue(np.isnan(ts.dayofyear))
419+
self.assertTrue(np.isnan(ts.week))
420+
self.assertTrue(np.isnan(ts.daysinmonth))
421+
self.assertTrue(np.isnan(ts.days_in_month))
422+
423+
372424
class TestDatetimeParsingWrappers(tm.TestCase):
373425
def test_does_not_convert_mixed_integer(self):
374426
bad_date_strings = (

pandas/tslib.pyx

+2-2
Original file line numberDiff line numberDiff line change
@@ -627,7 +627,7 @@ class NaTType(_NaT):
627627

628628
fields = ['year', 'quarter', 'month', 'day', 'hour',
629629
'minute', 'second', 'millisecond', 'microsecond', 'nanosecond',
630-
'week', 'dayofyear', 'days_in_month']
630+
'week', 'dayofyear', 'days_in_month', 'daysinmonth', 'dayofweek']
631631
for field in fields:
632632
prop = property(fget=lambda self: np.nan)
633633
setattr(NaTType, field, prop)
@@ -952,7 +952,7 @@ cdef class _Timestamp(datetime):
952952

953953
cpdef _get_field(self, field):
954954
out = get_date_field(np.array([self.value], dtype=np.int64), field)
955-
return out[0]
955+
return int(out[0])
956956

957957
cpdef _get_start_end_field(self, field):
958958
month_kw = self.freq.kwds.get('startingMonth', self.freq.kwds.get('month', 12)) if self.freq else 12

0 commit comments

Comments
 (0)