from __future__ import division, absolute_import, print_function import pickle import warnings import numpy import numpy as np import datetime from numpy.compat import asbytes from numpy.testing import ( TestCase, run_module_suite, assert_, assert_equal, assert_raises, assert_warns, dec ) # Use pytz to test out various time zones if available try: from pytz import timezone as tz _has_pytz = True except ImportError: _has_pytz = False class TestDateTime(TestCase): def test_datetime_dtype_creation(self): for unit in ['Y', 'M', 'W', 'D', 'h', 'm', 's', 'ms', 'us', 'ns', 'ps', 'fs', 'as']: dt1 = np.dtype('M8[750%s]' % unit) assert_(dt1 == np.dtype('datetime64[750%s]' % unit)) dt2 = np.dtype('m8[%s]' % unit) assert_(dt2 == np.dtype('timedelta64[%s]' % unit)) # Generic units shouldn't add [] to the end assert_equal(str(np.dtype("M8")), "datetime64") # Should be possible to specify the endianness assert_equal(np.dtype("=M8"), np.dtype("M8")) assert_equal(np.dtype("=M8[s]"), np.dtype("M8[s]")) assert_(np.dtype(">M8") == np.dtype("M8") or np.dtype("M8[D]") == np.dtype("M8[D]") or np.dtype("M8") != np.dtype("m8") == np.dtype("m8") or np.dtype("m8[D]") == np.dtype("m8[D]") or np.dtype("m8") != np.dtype(" Scalars assert_equal(np.datetime64(b, '[s]'), np.datetime64('NaT', '[s]')) assert_equal(np.datetime64(b, '[ms]'), np.datetime64('NaT', '[ms]')) assert_equal(np.datetime64(b, '[M]'), np.datetime64('NaT', '[M]')) assert_equal(np.datetime64(b, '[Y]'), np.datetime64('NaT', '[Y]')) assert_equal(np.datetime64(b, '[W]'), np.datetime64('NaT', '[W]')) # Arrays -> Scalars assert_equal(np.datetime64(a, '[s]'), np.datetime64('NaT', '[s]')) assert_equal(np.datetime64(a, '[ms]'), np.datetime64('NaT', '[ms]')) assert_equal(np.datetime64(a, '[M]'), np.datetime64('NaT', '[M]')) assert_equal(np.datetime64(a, '[Y]'), np.datetime64('NaT', '[Y]')) assert_equal(np.datetime64(a, '[W]'), np.datetime64('NaT', '[W]')) def test_days_creation(self): assert_equal(np.array('1599', dtype='M8[D]').astype('i8'), (1600-1970)*365 - (1972-1600)/4 + 3 - 365) assert_equal(np.array('1600', dtype='M8[D]').astype('i8'), (1600-1970)*365 - (1972-1600)/4 + 3) assert_equal(np.array('1601', dtype='M8[D]').astype('i8'), (1600-1970)*365 - (1972-1600)/4 + 3 + 366) assert_equal(np.array('1900', dtype='M8[D]').astype('i8'), (1900-1970)*365 - (1970-1900)//4) assert_equal(np.array('1901', dtype='M8[D]').astype('i8'), (1900-1970)*365 - (1970-1900)//4 + 365) assert_equal(np.array('1967', dtype='M8[D]').astype('i8'), -3*365 - 1) assert_equal(np.array('1968', dtype='M8[D]').astype('i8'), -2*365 - 1) assert_equal(np.array('1969', dtype='M8[D]').astype('i8'), -1*365) assert_equal(np.array('1970', dtype='M8[D]').astype('i8'), 0*365) assert_equal(np.array('1971', dtype='M8[D]').astype('i8'), 1*365) assert_equal(np.array('1972', dtype='M8[D]').astype('i8'), 2*365) assert_equal(np.array('1973', dtype='M8[D]').astype('i8'), 3*365 + 1) assert_equal(np.array('1974', dtype='M8[D]').astype('i8'), 4*365 + 1) assert_equal(np.array('2000', dtype='M8[D]').astype('i8'), (2000 - 1970)*365 + (2000 - 1972)//4) assert_equal(np.array('2001', dtype='M8[D]').astype('i8'), (2000 - 1970)*365 + (2000 - 1972)//4 + 366) assert_equal(np.array('2400', dtype='M8[D]').astype('i8'), (2400 - 1970)*365 + (2400 - 1972)//4 - 3) assert_equal(np.array('2401', dtype='M8[D]').astype('i8'), (2400 - 1970)*365 + (2400 - 1972)//4 - 3 + 366) assert_equal(np.array('1600-02-29', dtype='M8[D]').astype('i8'), (1600-1970)*365 - (1972-1600)//4 + 3 + 31 + 28) assert_equal(np.array('1600-03-01', dtype='M8[D]').astype('i8'), (1600-1970)*365 - (1972-1600)//4 + 3 + 31 + 29) assert_equal(np.array('2000-02-29', dtype='M8[D]').astype('i8'), (2000 - 1970)*365 + (2000 - 1972)//4 + 31 + 28) assert_equal(np.array('2000-03-01', dtype='M8[D]').astype('i8'), (2000 - 1970)*365 + (2000 - 1972)//4 + 31 + 29) assert_equal(np.array('2001-03-22', dtype='M8[D]').astype('i8'), (2000 - 1970)*365 + (2000 - 1972)//4 + 366 + 31 + 28 + 21) def test_days_to_pydate(self): assert_equal(np.array('1599', dtype='M8[D]').astype('O'), datetime.date(1599, 1, 1)) assert_equal(np.array('1600', dtype='M8[D]').astype('O'), datetime.date(1600, 1, 1)) assert_equal(np.array('1601', dtype='M8[D]').astype('O'), datetime.date(1601, 1, 1)) assert_equal(np.array('1900', dtype='M8[D]').astype('O'), datetime.date(1900, 1, 1)) assert_equal(np.array('1901', dtype='M8[D]').astype('O'), datetime.date(1901, 1, 1)) assert_equal(np.array('2000', dtype='M8[D]').astype('O'), datetime.date(2000, 1, 1)) assert_equal(np.array('2001', dtype='M8[D]').astype('O'), datetime.date(2001, 1, 1)) assert_equal(np.array('1600-02-29', dtype='M8[D]').astype('O'), datetime.date(1600, 2, 29)) assert_equal(np.array('1600-03-01', dtype='M8[D]').astype('O'), datetime.date(1600, 3, 1)) assert_equal(np.array('2001-03-22', dtype='M8[D]').astype('O'), datetime.date(2001, 3, 22)) def test_dtype_comparison(self): assert_(not (np.dtype('M8[us]') == np.dtype('M8[ms]'))) assert_(np.dtype('M8[us]') != np.dtype('M8[ms]')) assert_(np.dtype('M8[2D]') != np.dtype('M8[D]')) assert_(np.dtype('M8[D]') != np.dtype('M8[2D]')) def test_pydatetime_creation(self): a = np.array(['1960-03-12', datetime.date(1960, 3, 12)], dtype='M8[D]') assert_equal(a[0], a[1]) a = np.array(['1999-12-31', datetime.date(1999, 12, 31)], dtype='M8[D]') assert_equal(a[0], a[1]) a = np.array(['2000-01-01', datetime.date(2000, 1, 1)], dtype='M8[D]') assert_equal(a[0], a[1]) # Will fail if the date changes during the exact right moment a = np.array(['today', datetime.date.today()], dtype='M8[D]') assert_equal(a[0], a[1]) # datetime.datetime.now() returns local time, not UTC #a = np.array(['now', datetime.datetime.now()], dtype='M8[s]') #assert_equal(a[0], a[1]) # we can give a datetime.date time units assert_equal(np.array(datetime.date(1960, 3, 12), dtype='M8[s]'), np.array(np.datetime64('1960-03-12T00:00:00'))) def test_datetime_string_conversion(self): a = ['2011-03-16', '1920-01-01', '2013-05-19'] str_a = np.array(a, dtype='S') dt_a = np.array(a, dtype='M') str_b = np.empty_like(str_a) dt_b = np.empty_like(dt_a) # String to datetime assert_equal(dt_a, str_a.astype('M')) assert_equal(dt_a.dtype, str_a.astype('M').dtype) dt_b[...] = str_a assert_equal(dt_a, dt_b) # Datetime to string assert_equal(str_a, dt_a.astype('S0')) str_b[...] = dt_a assert_equal(str_a, str_b) # Convert the 'S' to 'U' str_a = str_a.astype('U') str_b = str_b.astype('U') # Unicode to datetime assert_equal(dt_a, str_a.astype('M')) assert_equal(dt_a.dtype, str_a.astype('M').dtype) dt_b[...] = str_a assert_equal(dt_a, dt_b) # Datetime to unicode assert_equal(str_a, dt_a.astype('U')) str_b[...] = dt_a assert_equal(str_a, str_b) def test_datetime_array_str(self): a = np.array(['2011-03-16', '1920-01-01', '2013-05-19'], dtype='M') assert_equal(str(a), "['2011-03-16' '1920-01-01' '2013-05-19']") a = np.array(['2011-03-16T13:55', '1920-01-01T03:12'], dtype='M') assert_equal(np.array2string(a, separator=', ', formatter={'datetime': lambda x: "'%s'" % np.datetime_as_string(x, timezone='UTC')}), "['2011-03-16T13:55Z', '1920-01-01T03:12Z']") # Check that one NaT doesn't corrupt subsequent entries a = np.array(['2010', 'NaT', '2030']).astype('M') assert_equal(str(a), "['2010' 'NaT' '2030']") def test_timedelta_array_str(self): a = np.array([-1, 0, 100], dtype='m') assert_equal(str(a), "[ -1 0 100]") a = np.array(['NaT', 'NaT'], dtype='m') assert_equal(str(a), "['NaT' 'NaT']") # Check right-alignment with NaTs a = np.array([-1, 'NaT', 0], dtype='m') assert_equal(str(a), "[ -1 'NaT' 0]") a = np.array([-1, 'NaT', 1234567], dtype='m') assert_equal(str(a), "[ -1 'NaT' 1234567]") def test_pickle(self): # Check that pickle roundtripping works dt = np.dtype('M8[7D]') assert_equal(pickle.loads(pickle.dumps(dt)), dt) dt = np.dtype('M8[W]') assert_equal(pickle.loads(pickle.dumps(dt)), dt) # Check that loading pickles from 1.6 works pkl = "cnumpy\ndtype\np0\n(S'M8'\np1\nI0\nI1\ntp2\nRp3\n" + \ "(I4\nS'<'\np4\nNNNI-1\nI-1\nI0\n((dp5\n(S'D'\np6\n" + \ "I7\nI1\nI1\ntp7\ntp8\ntp9\nb." assert_equal(pickle.loads(asbytes(pkl)), np.dtype(''\np4\nNNNI-1\nI-1\nI0\n((dp5\n(S'us'\np6\n" + \ "I1\nI1\nI1\ntp7\ntp8\ntp9\nb." assert_equal(pickle.loads(asbytes(pkl)), np.dtype('>M8[us]')) def test_setstate(self): "Verify that datetime dtype __setstate__ can handle bad arguments" dt = np.dtype('>M8[us]') assert_raises(ValueError, dt.__setstate__, (4, '>', None, None, None, -1, -1, 0, 1)) assert_(dt.__reduce__()[2] == np.dtype('>M8[us]').__reduce__()[2]) assert_raises(TypeError, dt.__setstate__, (4, '>', None, None, None, -1, -1, 0, ({}, 'xxx'))) assert_(dt.__reduce__()[2] == np.dtype('>M8[us]').__reduce__()[2]) def test_dtype_promotion(self): # datetime datetime computes the metadata gcd # timedelta timedelta computes the metadata gcd for mM in ['m', 'M']: assert_equal( np.promote_types(np.dtype(mM+'8[2Y]'), np.dtype(mM+'8[2Y]')), np.dtype(mM+'8[2Y]')) assert_equal( np.promote_types(np.dtype(mM+'8[12Y]'), np.dtype(mM+'8[15Y]')), np.dtype(mM+'8[3Y]')) assert_equal( np.promote_types(np.dtype(mM+'8[62M]'), np.dtype(mM+'8[24M]')), np.dtype(mM+'8[2M]')) assert_equal( np.promote_types(np.dtype(mM+'8[1W]'), np.dtype(mM+'8[2D]')), np.dtype(mM+'8[1D]')) assert_equal( np.promote_types(np.dtype(mM+'8[W]'), np.dtype(mM+'8[13s]')), np.dtype(mM+'8[s]')) assert_equal( np.promote_types(np.dtype(mM+'8[13W]'), np.dtype(mM+'8[49s]')), np.dtype(mM+'8[7s]')) # timedelta timedelta raises when there is no reasonable gcd assert_raises(TypeError, np.promote_types, np.dtype('m8[Y]'), np.dtype('m8[D]')) assert_raises(TypeError, np.promote_types, np.dtype('m8[M]'), np.dtype('m8[W]')) # timedelta timedelta may overflow with big unit ranges assert_raises(OverflowError, np.promote_types, np.dtype('m8[W]'), np.dtype('m8[fs]')) assert_raises(OverflowError, np.promote_types, np.dtype('m8[s]'), np.dtype('m8[as]')) def test_cast_overflow(self): # gh-4486 def cast(): numpy.datetime64("1971-01-01 00:00:00.000000000000000").astype("