1 2import numpy 3import numpy as np 4import datetime 5import pytest 6from numpy.testing import ( 7 assert_, assert_equal, assert_raises, assert_warns, suppress_warnings, 8 assert_raises_regex, 9 ) 10from numpy.compat import pickle 11 12# Use pytz to test out various time zones if available 13try: 14 from pytz import timezone as tz 15 _has_pytz = True 16except ImportError: 17 _has_pytz = False 18 19try: 20 RecursionError 21except NameError: 22 RecursionError = RuntimeError # python < 3.5 23 24 25class TestDateTime: 26 def test_datetime_dtype_creation(self): 27 for unit in ['Y', 'M', 'W', 'D', 28 'h', 'm', 's', 'ms', 'us', 29 'μs', # alias for us 30 'ns', 'ps', 'fs', 'as']: 31 dt1 = np.dtype('M8[750%s]' % unit) 32 assert_(dt1 == np.dtype('datetime64[750%s]' % unit)) 33 dt2 = np.dtype('m8[%s]' % unit) 34 assert_(dt2 == np.dtype('timedelta64[%s]' % unit)) 35 36 # Generic units shouldn't add [] to the end 37 assert_equal(str(np.dtype("M8")), "datetime64") 38 39 # Should be possible to specify the endianness 40 assert_equal(np.dtype("=M8"), np.dtype("M8")) 41 assert_equal(np.dtype("=M8[s]"), np.dtype("M8[s]")) 42 assert_(np.dtype(">M8") == np.dtype("M8") or 43 np.dtype("<M8") == np.dtype("M8")) 44 assert_(np.dtype(">M8[D]") == np.dtype("M8[D]") or 45 np.dtype("<M8[D]") == np.dtype("M8[D]")) 46 assert_(np.dtype(">M8") != np.dtype("<M8")) 47 48 assert_equal(np.dtype("=m8"), np.dtype("m8")) 49 assert_equal(np.dtype("=m8[s]"), np.dtype("m8[s]")) 50 assert_(np.dtype(">m8") == np.dtype("m8") or 51 np.dtype("<m8") == np.dtype("m8")) 52 assert_(np.dtype(">m8[D]") == np.dtype("m8[D]") or 53 np.dtype("<m8[D]") == np.dtype("m8[D]")) 54 assert_(np.dtype(">m8") != np.dtype("<m8")) 55 56 # Check that the parser rejects bad datetime types 57 assert_raises(TypeError, np.dtype, 'M8[badunit]') 58 assert_raises(TypeError, np.dtype, 'm8[badunit]') 59 assert_raises(TypeError, np.dtype, 'M8[YY]') 60 assert_raises(TypeError, np.dtype, 'm8[YY]') 61 assert_raises(TypeError, np.dtype, 'm4') 62 assert_raises(TypeError, np.dtype, 'M7') 63 assert_raises(TypeError, np.dtype, 'm7') 64 assert_raises(TypeError, np.dtype, 'M16') 65 assert_raises(TypeError, np.dtype, 'm16') 66 67 def test_datetime_casting_rules(self): 68 # Cannot cast safely/same_kind between timedelta and datetime 69 assert_(not np.can_cast('m8', 'M8', casting='same_kind')) 70 assert_(not np.can_cast('M8', 'm8', casting='same_kind')) 71 assert_(not np.can_cast('m8', 'M8', casting='safe')) 72 assert_(not np.can_cast('M8', 'm8', casting='safe')) 73 74 # Can cast safely/same_kind from integer to timedelta 75 assert_(np.can_cast('i8', 'm8', casting='same_kind')) 76 assert_(np.can_cast('i8', 'm8', casting='safe')) 77 assert_(np.can_cast('i4', 'm8', casting='same_kind')) 78 assert_(np.can_cast('i4', 'm8', casting='safe')) 79 assert_(np.can_cast('u4', 'm8', casting='same_kind')) 80 assert_(np.can_cast('u4', 'm8', casting='safe')) 81 82 # Cannot cast safely from unsigned integer of the same size, which 83 # could overflow 84 assert_(np.can_cast('u8', 'm8', casting='same_kind')) 85 assert_(not np.can_cast('u8', 'm8', casting='safe')) 86 87 # Cannot cast safely/same_kind from float to timedelta 88 assert_(not np.can_cast('f4', 'm8', casting='same_kind')) 89 assert_(not np.can_cast('f4', 'm8', casting='safe')) 90 91 # Cannot cast safely/same_kind from integer to datetime 92 assert_(not np.can_cast('i8', 'M8', casting='same_kind')) 93 assert_(not np.can_cast('i8', 'M8', casting='safe')) 94 95 # Cannot cast safely/same_kind from bool to datetime 96 assert_(not np.can_cast('b1', 'M8', casting='same_kind')) 97 assert_(not np.can_cast('b1', 'M8', casting='safe')) 98 # Can cast safely/same_kind from bool to timedelta 99 assert_(np.can_cast('b1', 'm8', casting='same_kind')) 100 assert_(np.can_cast('b1', 'm8', casting='safe')) 101 102 # Can cast datetime safely from months/years to days 103 assert_(np.can_cast('M8[M]', 'M8[D]', casting='safe')) 104 assert_(np.can_cast('M8[Y]', 'M8[D]', casting='safe')) 105 # Cannot cast timedelta safely from months/years to days 106 assert_(not np.can_cast('m8[M]', 'm8[D]', casting='safe')) 107 assert_(not np.can_cast('m8[Y]', 'm8[D]', casting='safe')) 108 # Can cast datetime same_kind from months/years to days 109 assert_(np.can_cast('M8[M]', 'M8[D]', casting='same_kind')) 110 assert_(np.can_cast('M8[Y]', 'M8[D]', casting='same_kind')) 111 # Can't cast timedelta same_kind from months/years to days 112 assert_(not np.can_cast('m8[M]', 'm8[D]', casting='same_kind')) 113 assert_(not np.can_cast('m8[Y]', 'm8[D]', casting='same_kind')) 114 # Can cast datetime same_kind across the date/time boundary 115 assert_(np.can_cast('M8[D]', 'M8[h]', casting='same_kind')) 116 # Can cast timedelta same_kind across the date/time boundary 117 assert_(np.can_cast('m8[D]', 'm8[h]', casting='same_kind')) 118 assert_(np.can_cast('m8[h]', 'm8[D]', casting='same_kind')) 119 120 # Cannot cast safely if the integer multiplier doesn't divide 121 assert_(not np.can_cast('M8[7h]', 'M8[3h]', casting='safe')) 122 assert_(not np.can_cast('M8[3h]', 'M8[6h]', casting='safe')) 123 # But can cast same_kind 124 assert_(np.can_cast('M8[7h]', 'M8[3h]', casting='same_kind')) 125 # Can cast safely if the integer multiplier does divide 126 assert_(np.can_cast('M8[6h]', 'M8[3h]', casting='safe')) 127 128 # We can always cast types with generic units (corresponding to NaT) to 129 # more specific types 130 assert_(np.can_cast('m8', 'm8[h]', casting='same_kind')) 131 assert_(np.can_cast('m8', 'm8[h]', casting='safe')) 132 assert_(np.can_cast('M8', 'M8[h]', casting='same_kind')) 133 assert_(np.can_cast('M8', 'M8[h]', casting='safe')) 134 # but not the other way around 135 assert_(not np.can_cast('m8[h]', 'm8', casting='same_kind')) 136 assert_(not np.can_cast('m8[h]', 'm8', casting='safe')) 137 assert_(not np.can_cast('M8[h]', 'M8', casting='same_kind')) 138 assert_(not np.can_cast('M8[h]', 'M8', casting='safe')) 139 140 def test_compare_generic_nat(self): 141 # regression tests for gh-6452 142 assert_(np.datetime64('NaT') != 143 np.datetime64('2000') + np.timedelta64('NaT')) 144 assert_(np.datetime64('NaT') != np.datetime64('NaT', 'us')) 145 assert_(np.datetime64('NaT', 'us') != np.datetime64('NaT')) 146 147 @pytest.mark.parametrize("size", [ 148 3, 21, 217, 1000]) 149 def test_datetime_nat_argsort_stability(self, size): 150 # NaT < NaT should be False internally for 151 # sort stability 152 expected = np.arange(size) 153 arr = np.tile(np.datetime64('NaT'), size) 154 assert_equal(np.argsort(arr, kind='mergesort'), expected) 155 156 @pytest.mark.parametrize("size", [ 157 3, 21, 217, 1000]) 158 def test_timedelta_nat_argsort_stability(self, size): 159 # NaT < NaT should be False internally for 160 # sort stability 161 expected = np.arange(size) 162 arr = np.tile(np.timedelta64('NaT'), size) 163 assert_equal(np.argsort(arr, kind='mergesort'), expected) 164 165 @pytest.mark.parametrize("arr, expected", [ 166 # the example provided in gh-12629 167 (['NaT', 1, 2, 3], 168 [1, 2, 3, 'NaT']), 169 # multiple NaTs 170 (['NaT', 9, 'NaT', -707], 171 [-707, 9, 'NaT', 'NaT']), 172 # this sort explores another code path for NaT 173 ([1, -2, 3, 'NaT'], 174 [-2, 1, 3, 'NaT']), 175 # 2-D array 176 ([[51, -220, 'NaT'], 177 [-17, 'NaT', -90]], 178 [[-220, 51, 'NaT'], 179 [-90, -17, 'NaT']]), 180 ]) 181 @pytest.mark.parametrize("dtype", [ 182 'M8[ns]', 'M8[us]', 183 'm8[ns]', 'm8[us]']) 184 def test_datetime_timedelta_sort_nat(self, arr, expected, dtype): 185 # fix for gh-12629 and gh-15063; NaT sorting to end of array 186 arr = np.array(arr, dtype=dtype) 187 expected = np.array(expected, dtype=dtype) 188 arr.sort() 189 assert_equal(arr, expected) 190 191 def test_datetime_scalar_construction(self): 192 # Construct with different units 193 assert_equal(np.datetime64('1950-03-12', 'D'), 194 np.datetime64('1950-03-12')) 195 assert_equal(np.datetime64('1950-03-12T13', 's'), 196 np.datetime64('1950-03-12T13', 'm')) 197 198 # Default construction means NaT 199 assert_equal(np.datetime64(), np.datetime64('NaT')) 200 201 # Some basic strings and repr 202 assert_equal(str(np.datetime64('NaT')), 'NaT') 203 assert_equal(repr(np.datetime64('NaT')), 204 "numpy.datetime64('NaT')") 205 assert_equal(str(np.datetime64('2011-02')), '2011-02') 206 assert_equal(repr(np.datetime64('2011-02')), 207 "numpy.datetime64('2011-02')") 208 209 # None gets constructed as NaT 210 assert_equal(np.datetime64(None), np.datetime64('NaT')) 211 212 # Default construction of NaT is in generic units 213 assert_equal(np.datetime64().dtype, np.dtype('M8')) 214 assert_equal(np.datetime64('NaT').dtype, np.dtype('M8')) 215 216 # Construction from integers requires a specified unit 217 assert_raises(ValueError, np.datetime64, 17) 218 219 # When constructing from a scalar or zero-dimensional array, 220 # it either keeps the units or you can override them. 221 a = np.datetime64('2000-03-18T16', 'h') 222 b = np.array('2000-03-18T16', dtype='M8[h]') 223 224 assert_equal(a.dtype, np.dtype('M8[h]')) 225 assert_equal(b.dtype, np.dtype('M8[h]')) 226 227 assert_equal(np.datetime64(a), a) 228 assert_equal(np.datetime64(a).dtype, np.dtype('M8[h]')) 229 230 assert_equal(np.datetime64(b), a) 231 assert_equal(np.datetime64(b).dtype, np.dtype('M8[h]')) 232 233 assert_equal(np.datetime64(a, 's'), a) 234 assert_equal(np.datetime64(a, 's').dtype, np.dtype('M8[s]')) 235 236 assert_equal(np.datetime64(b, 's'), a) 237 assert_equal(np.datetime64(b, 's').dtype, np.dtype('M8[s]')) 238 239 # Construction from datetime.date 240 assert_equal(np.datetime64('1945-03-25'), 241 np.datetime64(datetime.date(1945, 3, 25))) 242 assert_equal(np.datetime64('2045-03-25', 'D'), 243 np.datetime64(datetime.date(2045, 3, 25), 'D')) 244 # Construction from datetime.datetime 245 assert_equal(np.datetime64('1980-01-25T14:36:22.5'), 246 np.datetime64(datetime.datetime(1980, 1, 25, 247 14, 36, 22, 500000))) 248 249 # Construction with time units from a date is okay 250 assert_equal(np.datetime64('1920-03-13', 'h'), 251 np.datetime64('1920-03-13T00')) 252 assert_equal(np.datetime64('1920-03', 'm'), 253 np.datetime64('1920-03-01T00:00')) 254 assert_equal(np.datetime64('1920', 's'), 255 np.datetime64('1920-01-01T00:00:00')) 256 assert_equal(np.datetime64(datetime.date(2045, 3, 25), 'ms'), 257 np.datetime64('2045-03-25T00:00:00.000')) 258 259 # Construction with date units from a datetime is also okay 260 assert_equal(np.datetime64('1920-03-13T18', 'D'), 261 np.datetime64('1920-03-13')) 262 assert_equal(np.datetime64('1920-03-13T18:33:12', 'M'), 263 np.datetime64('1920-03')) 264 assert_equal(np.datetime64('1920-03-13T18:33:12.5', 'Y'), 265 np.datetime64('1920')) 266 267 def test_datetime_scalar_construction_timezone(self): 268 # verify that supplying an explicit timezone works, but is deprecated 269 with assert_warns(DeprecationWarning): 270 assert_equal(np.datetime64('2000-01-01T00Z'), 271 np.datetime64('2000-01-01T00')) 272 with assert_warns(DeprecationWarning): 273 assert_equal(np.datetime64('2000-01-01T00-08'), 274 np.datetime64('2000-01-01T08')) 275 276 def test_datetime_array_find_type(self): 277 dt = np.datetime64('1970-01-01', 'M') 278 arr = np.array([dt]) 279 assert_equal(arr.dtype, np.dtype('M8[M]')) 280 281 # at the moment, we don't automatically convert these to datetime64 282 283 dt = datetime.date(1970, 1, 1) 284 arr = np.array([dt]) 285 assert_equal(arr.dtype, np.dtype('O')) 286 287 dt = datetime.datetime(1970, 1, 1, 12, 30, 40) 288 arr = np.array([dt]) 289 assert_equal(arr.dtype, np.dtype('O')) 290 291 # find "supertype" for non-dates and dates 292 293 b = np.bool_(True) 294 dm = np.datetime64('1970-01-01', 'M') 295 d = datetime.date(1970, 1, 1) 296 dt = datetime.datetime(1970, 1, 1, 12, 30, 40) 297 298 arr = np.array([b, dm]) 299 assert_equal(arr.dtype, np.dtype('O')) 300 301 arr = np.array([b, d]) 302 assert_equal(arr.dtype, np.dtype('O')) 303 304 arr = np.array([b, dt]) 305 assert_equal(arr.dtype, np.dtype('O')) 306 307 arr = np.array([d, d]).astype('datetime64') 308 assert_equal(arr.dtype, np.dtype('M8[D]')) 309 310 arr = np.array([dt, dt]).astype('datetime64') 311 assert_equal(arr.dtype, np.dtype('M8[us]')) 312 313 @pytest.mark.parametrize("unit", [ 314 # test all date / time units and use 315 # "generic" to select generic unit 316 ("Y"), ("M"), ("W"), ("D"), ("h"), ("m"), 317 ("s"), ("ms"), ("us"), ("ns"), ("ps"), 318 ("fs"), ("as"), ("generic") ]) 319 def test_timedelta_np_int_construction(self, unit): 320 # regression test for gh-7617 321 if unit != "generic": 322 assert_equal(np.timedelta64(np.int64(123), unit), 323 np.timedelta64(123, unit)) 324 else: 325 assert_equal(np.timedelta64(np.int64(123)), 326 np.timedelta64(123)) 327 328 def test_timedelta_scalar_construction(self): 329 # Construct with different units 330 assert_equal(np.timedelta64(7, 'D'), 331 np.timedelta64(1, 'W')) 332 assert_equal(np.timedelta64(120, 's'), 333 np.timedelta64(2, 'm')) 334 335 # Default construction means 0 336 assert_equal(np.timedelta64(), np.timedelta64(0)) 337 338 # None gets constructed as NaT 339 assert_equal(np.timedelta64(None), np.timedelta64('NaT')) 340 341 # Some basic strings and repr 342 assert_equal(str(np.timedelta64('NaT')), 'NaT') 343 assert_equal(repr(np.timedelta64('NaT')), 344 "numpy.timedelta64('NaT')") 345 assert_equal(str(np.timedelta64(3, 's')), '3 seconds') 346 assert_equal(repr(np.timedelta64(-3, 's')), 347 "numpy.timedelta64(-3,'s')") 348 assert_equal(repr(np.timedelta64(12)), 349 "numpy.timedelta64(12)") 350 351 # Construction from an integer produces generic units 352 assert_equal(np.timedelta64(12).dtype, np.dtype('m8')) 353 354 # When constructing from a scalar or zero-dimensional array, 355 # it either keeps the units or you can override them. 356 a = np.timedelta64(2, 'h') 357 b = np.array(2, dtype='m8[h]') 358 359 assert_equal(a.dtype, np.dtype('m8[h]')) 360 assert_equal(b.dtype, np.dtype('m8[h]')) 361 362 assert_equal(np.timedelta64(a), a) 363 assert_equal(np.timedelta64(a).dtype, np.dtype('m8[h]')) 364 365 assert_equal(np.timedelta64(b), a) 366 assert_equal(np.timedelta64(b).dtype, np.dtype('m8[h]')) 367 368 assert_equal(np.timedelta64(a, 's'), a) 369 assert_equal(np.timedelta64(a, 's').dtype, np.dtype('m8[s]')) 370 371 assert_equal(np.timedelta64(b, 's'), a) 372 assert_equal(np.timedelta64(b, 's').dtype, np.dtype('m8[s]')) 373 374 # Construction from datetime.timedelta 375 assert_equal(np.timedelta64(5, 'D'), 376 np.timedelta64(datetime.timedelta(days=5))) 377 assert_equal(np.timedelta64(102347621, 's'), 378 np.timedelta64(datetime.timedelta(seconds=102347621))) 379 assert_equal(np.timedelta64(-10234760000, 'us'), 380 np.timedelta64(datetime.timedelta( 381 microseconds=-10234760000))) 382 assert_equal(np.timedelta64(10234760000, 'us'), 383 np.timedelta64(datetime.timedelta( 384 microseconds=10234760000))) 385 assert_equal(np.timedelta64(1023476, 'ms'), 386 np.timedelta64(datetime.timedelta(milliseconds=1023476))) 387 assert_equal(np.timedelta64(10, 'm'), 388 np.timedelta64(datetime.timedelta(minutes=10))) 389 assert_equal(np.timedelta64(281, 'h'), 390 np.timedelta64(datetime.timedelta(hours=281))) 391 assert_equal(np.timedelta64(28, 'W'), 392 np.timedelta64(datetime.timedelta(weeks=28))) 393 394 # Cannot construct across nonlinear time unit boundaries 395 a = np.timedelta64(3, 's') 396 assert_raises(TypeError, np.timedelta64, a, 'M') 397 assert_raises(TypeError, np.timedelta64, a, 'Y') 398 a = np.timedelta64(6, 'M') 399 assert_raises(TypeError, np.timedelta64, a, 'D') 400 assert_raises(TypeError, np.timedelta64, a, 'h') 401 a = np.timedelta64(1, 'Y') 402 assert_raises(TypeError, np.timedelta64, a, 'D') 403 assert_raises(TypeError, np.timedelta64, a, 'm') 404 a = datetime.timedelta(seconds=3) 405 assert_raises(TypeError, np.timedelta64, a, 'M') 406 assert_raises(TypeError, np.timedelta64, a, 'Y') 407 a = datetime.timedelta(weeks=3) 408 assert_raises(TypeError, np.timedelta64, a, 'M') 409 assert_raises(TypeError, np.timedelta64, a, 'Y') 410 a = datetime.timedelta() 411 assert_raises(TypeError, np.timedelta64, a, 'M') 412 assert_raises(TypeError, np.timedelta64, a, 'Y') 413 414 def test_timedelta_object_array_conversion(self): 415 # Regression test for gh-11096 416 inputs = [datetime.timedelta(28), 417 datetime.timedelta(30), 418 datetime.timedelta(31)] 419 expected = np.array([28, 30, 31], dtype='timedelta64[D]') 420 actual = np.array(inputs, dtype='timedelta64[D]') 421 assert_equal(expected, actual) 422 423 def test_timedelta_0_dim_object_array_conversion(self): 424 # Regression test for gh-11151 425 test = np.array(datetime.timedelta(seconds=20)) 426 actual = test.astype(np.timedelta64) 427 # expected value from the array constructor workaround 428 # described in above issue 429 expected = np.array(datetime.timedelta(seconds=20), 430 np.timedelta64) 431 assert_equal(actual, expected) 432 433 def test_timedelta_nat_format(self): 434 # gh-17552 435 assert_equal('NaT', '{0}'.format(np.timedelta64('nat'))) 436 437 def test_timedelta_scalar_construction_units(self): 438 # String construction detecting units 439 assert_equal(np.datetime64('2010').dtype, 440 np.dtype('M8[Y]')) 441 assert_equal(np.datetime64('2010-03').dtype, 442 np.dtype('M8[M]')) 443 assert_equal(np.datetime64('2010-03-12').dtype, 444 np.dtype('M8[D]')) 445 assert_equal(np.datetime64('2010-03-12T17').dtype, 446 np.dtype('M8[h]')) 447 assert_equal(np.datetime64('2010-03-12T17:15').dtype, 448 np.dtype('M8[m]')) 449 assert_equal(np.datetime64('2010-03-12T17:15:08').dtype, 450 np.dtype('M8[s]')) 451 452 assert_equal(np.datetime64('2010-03-12T17:15:08.1').dtype, 453 np.dtype('M8[ms]')) 454 assert_equal(np.datetime64('2010-03-12T17:15:08.12').dtype, 455 np.dtype('M8[ms]')) 456 assert_equal(np.datetime64('2010-03-12T17:15:08.123').dtype, 457 np.dtype('M8[ms]')) 458 459 assert_equal(np.datetime64('2010-03-12T17:15:08.1234').dtype, 460 np.dtype('M8[us]')) 461 assert_equal(np.datetime64('2010-03-12T17:15:08.12345').dtype, 462 np.dtype('M8[us]')) 463 assert_equal(np.datetime64('2010-03-12T17:15:08.123456').dtype, 464 np.dtype('M8[us]')) 465 466 assert_equal(np.datetime64('1970-01-01T00:00:02.1234567').dtype, 467 np.dtype('M8[ns]')) 468 assert_equal(np.datetime64('1970-01-01T00:00:02.12345678').dtype, 469 np.dtype('M8[ns]')) 470 assert_equal(np.datetime64('1970-01-01T00:00:02.123456789').dtype, 471 np.dtype('M8[ns]')) 472 473 assert_equal(np.datetime64('1970-01-01T00:00:02.1234567890').dtype, 474 np.dtype('M8[ps]')) 475 assert_equal(np.datetime64('1970-01-01T00:00:02.12345678901').dtype, 476 np.dtype('M8[ps]')) 477 assert_equal(np.datetime64('1970-01-01T00:00:02.123456789012').dtype, 478 np.dtype('M8[ps]')) 479 480 assert_equal(np.datetime64( 481 '1970-01-01T00:00:02.1234567890123').dtype, 482 np.dtype('M8[fs]')) 483 assert_equal(np.datetime64( 484 '1970-01-01T00:00:02.12345678901234').dtype, 485 np.dtype('M8[fs]')) 486 assert_equal(np.datetime64( 487 '1970-01-01T00:00:02.123456789012345').dtype, 488 np.dtype('M8[fs]')) 489 490 assert_equal(np.datetime64( 491 '1970-01-01T00:00:02.1234567890123456').dtype, 492 np.dtype('M8[as]')) 493 assert_equal(np.datetime64( 494 '1970-01-01T00:00:02.12345678901234567').dtype, 495 np.dtype('M8[as]')) 496 assert_equal(np.datetime64( 497 '1970-01-01T00:00:02.123456789012345678').dtype, 498 np.dtype('M8[as]')) 499 500 # Python date object 501 assert_equal(np.datetime64(datetime.date(2010, 4, 16)).dtype, 502 np.dtype('M8[D]')) 503 504 # Python datetime object 505 assert_equal(np.datetime64( 506 datetime.datetime(2010, 4, 16, 13, 45, 18)).dtype, 507 np.dtype('M8[us]')) 508 509 # 'today' special value 510 assert_equal(np.datetime64('today').dtype, 511 np.dtype('M8[D]')) 512 513 # 'now' special value 514 assert_equal(np.datetime64('now').dtype, 515 np.dtype('M8[s]')) 516 517 def test_datetime_nat_casting(self): 518 a = np.array('NaT', dtype='M8[D]') 519 b = np.datetime64('NaT', '[D]') 520 521 # Arrays 522 assert_equal(a.astype('M8[s]'), np.array('NaT', dtype='M8[s]')) 523 assert_equal(a.astype('M8[ms]'), np.array('NaT', dtype='M8[ms]')) 524 assert_equal(a.astype('M8[M]'), np.array('NaT', dtype='M8[M]')) 525 assert_equal(a.astype('M8[Y]'), np.array('NaT', dtype='M8[Y]')) 526 assert_equal(a.astype('M8[W]'), np.array('NaT', dtype='M8[W]')) 527 528 # Scalars -> Scalars 529 assert_equal(np.datetime64(b, '[s]'), np.datetime64('NaT', '[s]')) 530 assert_equal(np.datetime64(b, '[ms]'), np.datetime64('NaT', '[ms]')) 531 assert_equal(np.datetime64(b, '[M]'), np.datetime64('NaT', '[M]')) 532 assert_equal(np.datetime64(b, '[Y]'), np.datetime64('NaT', '[Y]')) 533 assert_equal(np.datetime64(b, '[W]'), np.datetime64('NaT', '[W]')) 534 535 # Arrays -> Scalars 536 assert_equal(np.datetime64(a, '[s]'), np.datetime64('NaT', '[s]')) 537 assert_equal(np.datetime64(a, '[ms]'), np.datetime64('NaT', '[ms]')) 538 assert_equal(np.datetime64(a, '[M]'), np.datetime64('NaT', '[M]')) 539 assert_equal(np.datetime64(a, '[Y]'), np.datetime64('NaT', '[Y]')) 540 assert_equal(np.datetime64(a, '[W]'), np.datetime64('NaT', '[W]')) 541 542 # NaN -> NaT 543 nan = np.array([np.nan] * 8) 544 fnan = nan.astype('f') 545 lnan = nan.astype('g') 546 cnan = nan.astype('D') 547 cfnan = nan.astype('F') 548 clnan = nan.astype('G') 549 550 nat = np.array([np.datetime64('NaT')] * 8) 551 assert_equal(nan.astype('M8[ns]'), nat) 552 assert_equal(fnan.astype('M8[ns]'), nat) 553 assert_equal(lnan.astype('M8[ns]'), nat) 554 assert_equal(cnan.astype('M8[ns]'), nat) 555 assert_equal(cfnan.astype('M8[ns]'), nat) 556 assert_equal(clnan.astype('M8[ns]'), nat) 557 558 nat = np.array([np.timedelta64('NaT')] * 8) 559 assert_equal(nan.astype('timedelta64[ns]'), nat) 560 assert_equal(fnan.astype('timedelta64[ns]'), nat) 561 assert_equal(lnan.astype('timedelta64[ns]'), nat) 562 assert_equal(cnan.astype('timedelta64[ns]'), nat) 563 assert_equal(cfnan.astype('timedelta64[ns]'), nat) 564 assert_equal(clnan.astype('timedelta64[ns]'), nat) 565 566 def test_days_creation(self): 567 assert_equal(np.array('1599', dtype='M8[D]').astype('i8'), 568 (1600-1970)*365 - (1972-1600)/4 + 3 - 365) 569 assert_equal(np.array('1600', dtype='M8[D]').astype('i8'), 570 (1600-1970)*365 - (1972-1600)/4 + 3) 571 assert_equal(np.array('1601', dtype='M8[D]').astype('i8'), 572 (1600-1970)*365 - (1972-1600)/4 + 3 + 366) 573 assert_equal(np.array('1900', dtype='M8[D]').astype('i8'), 574 (1900-1970)*365 - (1970-1900)//4) 575 assert_equal(np.array('1901', dtype='M8[D]').astype('i8'), 576 (1900-1970)*365 - (1970-1900)//4 + 365) 577 assert_equal(np.array('1967', dtype='M8[D]').astype('i8'), -3*365 - 1) 578 assert_equal(np.array('1968', dtype='M8[D]').astype('i8'), -2*365 - 1) 579 assert_equal(np.array('1969', dtype='M8[D]').astype('i8'), -1*365) 580 assert_equal(np.array('1970', dtype='M8[D]').astype('i8'), 0*365) 581 assert_equal(np.array('1971', dtype='M8[D]').astype('i8'), 1*365) 582 assert_equal(np.array('1972', dtype='M8[D]').astype('i8'), 2*365) 583 assert_equal(np.array('1973', dtype='M8[D]').astype('i8'), 3*365 + 1) 584 assert_equal(np.array('1974', dtype='M8[D]').astype('i8'), 4*365 + 1) 585 assert_equal(np.array('2000', dtype='M8[D]').astype('i8'), 586 (2000 - 1970)*365 + (2000 - 1972)//4) 587 assert_equal(np.array('2001', dtype='M8[D]').astype('i8'), 588 (2000 - 1970)*365 + (2000 - 1972)//4 + 366) 589 assert_equal(np.array('2400', dtype='M8[D]').astype('i8'), 590 (2400 - 1970)*365 + (2400 - 1972)//4 - 3) 591 assert_equal(np.array('2401', dtype='M8[D]').astype('i8'), 592 (2400 - 1970)*365 + (2400 - 1972)//4 - 3 + 366) 593 594 assert_equal(np.array('1600-02-29', dtype='M8[D]').astype('i8'), 595 (1600-1970)*365 - (1972-1600)//4 + 3 + 31 + 28) 596 assert_equal(np.array('1600-03-01', dtype='M8[D]').astype('i8'), 597 (1600-1970)*365 - (1972-1600)//4 + 3 + 31 + 29) 598 assert_equal(np.array('2000-02-29', dtype='M8[D]').astype('i8'), 599 (2000 - 1970)*365 + (2000 - 1972)//4 + 31 + 28) 600 assert_equal(np.array('2000-03-01', dtype='M8[D]').astype('i8'), 601 (2000 - 1970)*365 + (2000 - 1972)//4 + 31 + 29) 602 assert_equal(np.array('2001-03-22', dtype='M8[D]').astype('i8'), 603 (2000 - 1970)*365 + (2000 - 1972)//4 + 366 + 31 + 28 + 21) 604 605 def test_days_to_pydate(self): 606 assert_equal(np.array('1599', dtype='M8[D]').astype('O'), 607 datetime.date(1599, 1, 1)) 608 assert_equal(np.array('1600', dtype='M8[D]').astype('O'), 609 datetime.date(1600, 1, 1)) 610 assert_equal(np.array('1601', dtype='M8[D]').astype('O'), 611 datetime.date(1601, 1, 1)) 612 assert_equal(np.array('1900', dtype='M8[D]').astype('O'), 613 datetime.date(1900, 1, 1)) 614 assert_equal(np.array('1901', dtype='M8[D]').astype('O'), 615 datetime.date(1901, 1, 1)) 616 assert_equal(np.array('2000', dtype='M8[D]').astype('O'), 617 datetime.date(2000, 1, 1)) 618 assert_equal(np.array('2001', dtype='M8[D]').astype('O'), 619 datetime.date(2001, 1, 1)) 620 assert_equal(np.array('1600-02-29', dtype='M8[D]').astype('O'), 621 datetime.date(1600, 2, 29)) 622 assert_equal(np.array('1600-03-01', dtype='M8[D]').astype('O'), 623 datetime.date(1600, 3, 1)) 624 assert_equal(np.array('2001-03-22', dtype='M8[D]').astype('O'), 625 datetime.date(2001, 3, 22)) 626 627 def test_dtype_comparison(self): 628 assert_(not (np.dtype('M8[us]') == np.dtype('M8[ms]'))) 629 assert_(np.dtype('M8[us]') != np.dtype('M8[ms]')) 630 assert_(np.dtype('M8[2D]') != np.dtype('M8[D]')) 631 assert_(np.dtype('M8[D]') != np.dtype('M8[2D]')) 632 633 def test_pydatetime_creation(self): 634 a = np.array(['1960-03-12', datetime.date(1960, 3, 12)], dtype='M8[D]') 635 assert_equal(a[0], a[1]) 636 a = np.array(['1999-12-31', datetime.date(1999, 12, 31)], dtype='M8[D]') 637 assert_equal(a[0], a[1]) 638 a = np.array(['2000-01-01', datetime.date(2000, 1, 1)], dtype='M8[D]') 639 assert_equal(a[0], a[1]) 640 # Will fail if the date changes during the exact right moment 641 a = np.array(['today', datetime.date.today()], dtype='M8[D]') 642 assert_equal(a[0], a[1]) 643 # datetime.datetime.now() returns local time, not UTC 644 #a = np.array(['now', datetime.datetime.now()], dtype='M8[s]') 645 #assert_equal(a[0], a[1]) 646 647 # we can give a datetime.date time units 648 assert_equal(np.array(datetime.date(1960, 3, 12), dtype='M8[s]'), 649 np.array(np.datetime64('1960-03-12T00:00:00'))) 650 651 def test_datetime_string_conversion(self): 652 a = ['2011-03-16', '1920-01-01', '2013-05-19'] 653 str_a = np.array(a, dtype='S') 654 uni_a = np.array(a, dtype='U') 655 dt_a = np.array(a, dtype='M') 656 657 # String to datetime 658 assert_equal(dt_a, str_a.astype('M')) 659 assert_equal(dt_a.dtype, str_a.astype('M').dtype) 660 dt_b = np.empty_like(dt_a) 661 dt_b[...] = str_a 662 assert_equal(dt_a, dt_b) 663 664 # Datetime to string 665 assert_equal(str_a, dt_a.astype('S0')) 666 str_b = np.empty_like(str_a) 667 str_b[...] = dt_a 668 assert_equal(str_a, str_b) 669 670 # Unicode to datetime 671 assert_equal(dt_a, uni_a.astype('M')) 672 assert_equal(dt_a.dtype, uni_a.astype('M').dtype) 673 dt_b = np.empty_like(dt_a) 674 dt_b[...] = uni_a 675 assert_equal(dt_a, dt_b) 676 677 # Datetime to unicode 678 assert_equal(uni_a, dt_a.astype('U')) 679 uni_b = np.empty_like(uni_a) 680 uni_b[...] = dt_a 681 assert_equal(uni_a, uni_b) 682 683 # Datetime to long string - gh-9712 684 assert_equal(str_a, dt_a.astype((np.string_, 128))) 685 str_b = np.empty(str_a.shape, dtype=(np.string_, 128)) 686 str_b[...] = dt_a 687 assert_equal(str_a, str_b) 688 689 def test_datetime_array_str(self): 690 a = np.array(['2011-03-16', '1920-01-01', '2013-05-19'], dtype='M') 691 assert_equal(str(a), "['2011-03-16' '1920-01-01' '2013-05-19']") 692 693 a = np.array(['2011-03-16T13:55', '1920-01-01T03:12'], dtype='M') 694 assert_equal(np.array2string(a, separator=', ', 695 formatter={'datetime': lambda x: 696 "'%s'" % np.datetime_as_string(x, timezone='UTC')}), 697 "['2011-03-16T13:55Z', '1920-01-01T03:12Z']") 698 699 # Check that one NaT doesn't corrupt subsequent entries 700 a = np.array(['2010', 'NaT', '2030']).astype('M') 701 assert_equal(str(a), "['2010' 'NaT' '2030']") 702 703 def test_timedelta_array_str(self): 704 a = np.array([-1, 0, 100], dtype='m') 705 assert_equal(str(a), "[ -1 0 100]") 706 a = np.array(['NaT', 'NaT'], dtype='m') 707 assert_equal(str(a), "['NaT' 'NaT']") 708 # Check right-alignment with NaTs 709 a = np.array([-1, 'NaT', 0], dtype='m') 710 assert_equal(str(a), "[ -1 'NaT' 0]") 711 a = np.array([-1, 'NaT', 1234567], dtype='m') 712 assert_equal(str(a), "[ -1 'NaT' 1234567]") 713 714 # Test with other byteorder: 715 a = np.array([-1, 'NaT', 1234567], dtype='>m') 716 assert_equal(str(a), "[ -1 'NaT' 1234567]") 717 a = np.array([-1, 'NaT', 1234567], dtype='<m') 718 assert_equal(str(a), "[ -1 'NaT' 1234567]") 719 720 def test_pickle(self): 721 # Check that pickle roundtripping works 722 for proto in range(2, pickle.HIGHEST_PROTOCOL + 1): 723 dt = np.dtype('M8[7D]') 724 assert_equal(pickle.loads(pickle.dumps(dt, protocol=proto)), dt) 725 dt = np.dtype('M8[W]') 726 assert_equal(pickle.loads(pickle.dumps(dt, protocol=proto)), dt) 727 scalar = np.datetime64('2016-01-01T00:00:00.000000000') 728 assert_equal(pickle.loads(pickle.dumps(scalar, protocol=proto)), 729 scalar) 730 delta = scalar - np.datetime64('2015-01-01T00:00:00.000000000') 731 assert_equal(pickle.loads(pickle.dumps(delta, protocol=proto)), 732 delta) 733 734 # Check that loading pickles from 1.6 works 735 pkl = b"cnumpy\ndtype\np0\n(S'M8'\np1\nI0\nI1\ntp2\nRp3\n" + \ 736 b"(I4\nS'<'\np4\nNNNI-1\nI-1\nI0\n((dp5\n(S'D'\np6\n" + \ 737 b"I7\nI1\nI1\ntp7\ntp8\ntp9\nb." 738 assert_equal(pickle.loads(pkl), np.dtype('<M8[7D]')) 739 pkl = b"cnumpy\ndtype\np0\n(S'M8'\np1\nI0\nI1\ntp2\nRp3\n" + \ 740 b"(I4\nS'<'\np4\nNNNI-1\nI-1\nI0\n((dp5\n(S'W'\np6\n" + \ 741 b"I1\nI1\nI1\ntp7\ntp8\ntp9\nb." 742 assert_equal(pickle.loads(pkl), np.dtype('<M8[W]')) 743 pkl = b"cnumpy\ndtype\np0\n(S'M8'\np1\nI0\nI1\ntp2\nRp3\n" + \ 744 b"(I4\nS'>'\np4\nNNNI-1\nI-1\nI0\n((dp5\n(S'us'\np6\n" + \ 745 b"I1\nI1\nI1\ntp7\ntp8\ntp9\nb." 746 assert_equal(pickle.loads(pkl), np.dtype('>M8[us]')) 747 748 def test_setstate(self): 749 "Verify that datetime dtype __setstate__ can handle bad arguments" 750 dt = np.dtype('>M8[us]') 751 assert_raises(ValueError, dt.__setstate__, (4, '>', None, None, None, -1, -1, 0, 1)) 752 assert_(dt.__reduce__()[2] == np.dtype('>M8[us]').__reduce__()[2]) 753 assert_raises(TypeError, dt.__setstate__, (4, '>', None, None, None, -1, -1, 0, ({}, 'xxx'))) 754 assert_(dt.__reduce__()[2] == np.dtype('>M8[us]').__reduce__()[2]) 755 756 def test_dtype_promotion(self): 757 # datetime <op> datetime computes the metadata gcd 758 # timedelta <op> timedelta computes the metadata gcd 759 for mM in ['m', 'M']: 760 assert_equal( 761 np.promote_types(np.dtype(mM+'8[2Y]'), np.dtype(mM+'8[2Y]')), 762 np.dtype(mM+'8[2Y]')) 763 assert_equal( 764 np.promote_types(np.dtype(mM+'8[12Y]'), np.dtype(mM+'8[15Y]')), 765 np.dtype(mM+'8[3Y]')) 766 assert_equal( 767 np.promote_types(np.dtype(mM+'8[62M]'), np.dtype(mM+'8[24M]')), 768 np.dtype(mM+'8[2M]')) 769 assert_equal( 770 np.promote_types(np.dtype(mM+'8[1W]'), np.dtype(mM+'8[2D]')), 771 np.dtype(mM+'8[1D]')) 772 assert_equal( 773 np.promote_types(np.dtype(mM+'8[W]'), np.dtype(mM+'8[13s]')), 774 np.dtype(mM+'8[s]')) 775 assert_equal( 776 np.promote_types(np.dtype(mM+'8[13W]'), np.dtype(mM+'8[49s]')), 777 np.dtype(mM+'8[7s]')) 778 # timedelta <op> timedelta raises when there is no reasonable gcd 779 assert_raises(TypeError, np.promote_types, 780 np.dtype('m8[Y]'), np.dtype('m8[D]')) 781 assert_raises(TypeError, np.promote_types, 782 np.dtype('m8[M]'), np.dtype('m8[W]')) 783 # timedelta and float cannot be safely cast with each other 784 assert_raises(TypeError, np.promote_types, "float32", "m8") 785 assert_raises(TypeError, np.promote_types, "m8", "float32") 786 assert_raises(TypeError, np.promote_types, "uint64", "m8") 787 assert_raises(TypeError, np.promote_types, "m8", "uint64") 788 789 # timedelta <op> timedelta may overflow with big unit ranges 790 assert_raises(OverflowError, np.promote_types, 791 np.dtype('m8[W]'), np.dtype('m8[fs]')) 792 assert_raises(OverflowError, np.promote_types, 793 np.dtype('m8[s]'), np.dtype('m8[as]')) 794 795 def test_cast_overflow(self): 796 # gh-4486 797 def cast(): 798 numpy.datetime64("1971-01-01 00:00:00.000000000000000").astype("<M8[D]") 799 assert_raises(OverflowError, cast) 800 801 def cast2(): 802 numpy.datetime64("2014").astype("<M8[fs]") 803 assert_raises(OverflowError, cast2) 804 805 def test_pyobject_roundtrip(self): 806 # All datetime types should be able to roundtrip through object 807 a = np.array([0, 0, 0, 0, 0, 0, 0, 0, 0, 808 -1020040340, -2942398, -1, 0, 1, 234523453, 1199164176], 809 dtype=np.int64) 810 # With date units 811 for unit in ['M8[D]', 'M8[W]', 'M8[M]', 'M8[Y]']: 812 b = a.copy().view(dtype=unit) 813 b[0] = '-0001-01-01' 814 b[1] = '-0001-12-31' 815 b[2] = '0000-01-01' 816 b[3] = '0001-01-01' 817 b[4] = '1969-12-31' 818 b[5] = '1970-01-01' 819 b[6] = '9999-12-31' 820 b[7] = '10000-01-01' 821 b[8] = 'NaT' 822 823 assert_equal(b.astype(object).astype(unit), b, 824 "Error roundtripping unit %s" % unit) 825 # With time units 826 for unit in ['M8[as]', 'M8[16fs]', 'M8[ps]', 'M8[us]', 827 'M8[300as]', 'M8[20us]']: 828 b = a.copy().view(dtype=unit) 829 b[0] = '-0001-01-01T00' 830 b[1] = '-0001-12-31T00' 831 b[2] = '0000-01-01T00' 832 b[3] = '0001-01-01T00' 833 b[4] = '1969-12-31T23:59:59.999999' 834 b[5] = '1970-01-01T00' 835 b[6] = '9999-12-31T23:59:59.999999' 836 b[7] = '10000-01-01T00' 837 b[8] = 'NaT' 838 839 assert_equal(b.astype(object).astype(unit), b, 840 "Error roundtripping unit %s" % unit) 841 842 def test_month_truncation(self): 843 # Make sure that months are truncating correctly 844 assert_equal(np.array('1945-03-01', dtype='M8[M]'), 845 np.array('1945-03-31', dtype='M8[M]')) 846 assert_equal(np.array('1969-11-01', dtype='M8[M]'), 847 np.array('1969-11-30T23:59:59.99999', dtype='M').astype('M8[M]')) 848 assert_equal(np.array('1969-12-01', dtype='M8[M]'), 849 np.array('1969-12-31T23:59:59.99999', dtype='M').astype('M8[M]')) 850 assert_equal(np.array('1970-01-01', dtype='M8[M]'), 851 np.array('1970-01-31T23:59:59.99999', dtype='M').astype('M8[M]')) 852 assert_equal(np.array('1980-02-01', dtype='M8[M]'), 853 np.array('1980-02-29T23:59:59.99999', dtype='M').astype('M8[M]')) 854 855 def test_different_unit_comparison(self): 856 # Check some years with date units 857 for unit1 in ['Y', 'M', 'D']: 858 dt1 = np.dtype('M8[%s]' % unit1) 859 for unit2 in ['Y', 'M', 'D']: 860 dt2 = np.dtype('M8[%s]' % unit2) 861 assert_equal(np.array('1945', dtype=dt1), 862 np.array('1945', dtype=dt2)) 863 assert_equal(np.array('1970', dtype=dt1), 864 np.array('1970', dtype=dt2)) 865 assert_equal(np.array('9999', dtype=dt1), 866 np.array('9999', dtype=dt2)) 867 assert_equal(np.array('10000', dtype=dt1), 868 np.array('10000-01-01', dtype=dt2)) 869 assert_equal(np.datetime64('1945', unit1), 870 np.datetime64('1945', unit2)) 871 assert_equal(np.datetime64('1970', unit1), 872 np.datetime64('1970', unit2)) 873 assert_equal(np.datetime64('9999', unit1), 874 np.datetime64('9999', unit2)) 875 assert_equal(np.datetime64('10000', unit1), 876 np.datetime64('10000-01-01', unit2)) 877 # Check some datetimes with time units 878 for unit1 in ['6h', 'h', 'm', 's', '10ms', 'ms', 'us']: 879 dt1 = np.dtype('M8[%s]' % unit1) 880 for unit2 in ['h', 'm', 's', 'ms', 'us']: 881 dt2 = np.dtype('M8[%s]' % unit2) 882 assert_equal(np.array('1945-03-12T18', dtype=dt1), 883 np.array('1945-03-12T18', dtype=dt2)) 884 assert_equal(np.array('1970-03-12T18', dtype=dt1), 885 np.array('1970-03-12T18', dtype=dt2)) 886 assert_equal(np.array('9999-03-12T18', dtype=dt1), 887 np.array('9999-03-12T18', dtype=dt2)) 888 assert_equal(np.array('10000-01-01T00', dtype=dt1), 889 np.array('10000-01-01T00', dtype=dt2)) 890 assert_equal(np.datetime64('1945-03-12T18', unit1), 891 np.datetime64('1945-03-12T18', unit2)) 892 assert_equal(np.datetime64('1970-03-12T18', unit1), 893 np.datetime64('1970-03-12T18', unit2)) 894 assert_equal(np.datetime64('9999-03-12T18', unit1), 895 np.datetime64('9999-03-12T18', unit2)) 896 assert_equal(np.datetime64('10000-01-01T00', unit1), 897 np.datetime64('10000-01-01T00', unit2)) 898 # Check some days with units that won't overflow 899 for unit1 in ['D', '12h', 'h', 'm', 's', '4s', 'ms', 'us']: 900 dt1 = np.dtype('M8[%s]' % unit1) 901 for unit2 in ['D', 'h', 'm', 's', 'ms', 'us']: 902 dt2 = np.dtype('M8[%s]' % unit2) 903 assert_(np.equal(np.array('1932-02-17', dtype='M').astype(dt1), 904 np.array('1932-02-17T00:00:00', dtype='M').astype(dt2), 905 casting='unsafe')) 906 assert_(np.equal(np.array('10000-04-27', dtype='M').astype(dt1), 907 np.array('10000-04-27T00:00:00', dtype='M').astype(dt2), 908 casting='unsafe')) 909 910 # Shouldn't be able to compare datetime and timedelta 911 # TODO: Changing to 'same_kind' or 'safe' casting in the ufuncs by 912 # default is needed to properly catch this kind of thing... 913 a = np.array('2012-12-21', dtype='M8[D]') 914 b = np.array(3, dtype='m8[D]') 915 #assert_raises(TypeError, np.less, a, b) 916 assert_raises(TypeError, np.less, a, b, casting='same_kind') 917 918 def test_datetime_like(self): 919 a = np.array([3], dtype='m8[4D]') 920 b = np.array(['2012-12-21'], dtype='M8[D]') 921 922 assert_equal(np.ones_like(a).dtype, a.dtype) 923 assert_equal(np.zeros_like(a).dtype, a.dtype) 924 assert_equal(np.empty_like(a).dtype, a.dtype) 925 assert_equal(np.ones_like(b).dtype, b.dtype) 926 assert_equal(np.zeros_like(b).dtype, b.dtype) 927 assert_equal(np.empty_like(b).dtype, b.dtype) 928 929 def test_datetime_unary(self): 930 for tda, tdb, tdzero, tdone, tdmone in \ 931 [ 932 # One-dimensional arrays 933 (np.array([3], dtype='m8[D]'), 934 np.array([-3], dtype='m8[D]'), 935 np.array([0], dtype='m8[D]'), 936 np.array([1], dtype='m8[D]'), 937 np.array([-1], dtype='m8[D]')), 938 # NumPy scalars 939 (np.timedelta64(3, '[D]'), 940 np.timedelta64(-3, '[D]'), 941 np.timedelta64(0, '[D]'), 942 np.timedelta64(1, '[D]'), 943 np.timedelta64(-1, '[D]'))]: 944 # negative ufunc 945 assert_equal(-tdb, tda) 946 assert_equal((-tdb).dtype, tda.dtype) 947 assert_equal(np.negative(tdb), tda) 948 assert_equal(np.negative(tdb).dtype, tda.dtype) 949 950 # positive ufunc 951 assert_equal(np.positive(tda), tda) 952 assert_equal(np.positive(tda).dtype, tda.dtype) 953 assert_equal(np.positive(tdb), tdb) 954 assert_equal(np.positive(tdb).dtype, tdb.dtype) 955 956 # absolute ufunc 957 assert_equal(np.absolute(tdb), tda) 958 assert_equal(np.absolute(tdb).dtype, tda.dtype) 959 960 # sign ufunc 961 assert_equal(np.sign(tda), tdone) 962 assert_equal(np.sign(tdb), tdmone) 963 assert_equal(np.sign(tdzero), tdzero) 964 assert_equal(np.sign(tda).dtype, tda.dtype) 965 966 # The ufuncs always produce native-endian results 967 assert_ 968 969 def test_datetime_add(self): 970 for dta, dtb, dtc, dtnat, tda, tdb, tdc in \ 971 [ 972 # One-dimensional arrays 973 (np.array(['2012-12-21'], dtype='M8[D]'), 974 np.array(['2012-12-24'], dtype='M8[D]'), 975 np.array(['2012-12-21T11'], dtype='M8[h]'), 976 np.array(['NaT'], dtype='M8[D]'), 977 np.array([3], dtype='m8[D]'), 978 np.array([11], dtype='m8[h]'), 979 np.array([3*24 + 11], dtype='m8[h]')), 980 # NumPy scalars 981 (np.datetime64('2012-12-21', '[D]'), 982 np.datetime64('2012-12-24', '[D]'), 983 np.datetime64('2012-12-21T11', '[h]'), 984 np.datetime64('NaT', '[D]'), 985 np.timedelta64(3, '[D]'), 986 np.timedelta64(11, '[h]'), 987 np.timedelta64(3*24 + 11, '[h]'))]: 988 # m8 + m8 989 assert_equal(tda + tdb, tdc) 990 assert_equal((tda + tdb).dtype, np.dtype('m8[h]')) 991 # m8 + bool 992 assert_equal(tdb + True, tdb + 1) 993 assert_equal((tdb + True).dtype, np.dtype('m8[h]')) 994 # m8 + int 995 assert_equal(tdb + 3*24, tdc) 996 assert_equal((tdb + 3*24).dtype, np.dtype('m8[h]')) 997 # bool + m8 998 assert_equal(False + tdb, tdb) 999 assert_equal((False + tdb).dtype, np.dtype('m8[h]')) 1000 # int + m8 1001 assert_equal(3*24 + tdb, tdc) 1002 assert_equal((3*24 + tdb).dtype, np.dtype('m8[h]')) 1003 # M8 + bool 1004 assert_equal(dta + True, dta + 1) 1005 assert_equal(dtnat + True, dtnat) 1006 assert_equal((dta + True).dtype, np.dtype('M8[D]')) 1007 # M8 + int 1008 assert_equal(dta + 3, dtb) 1009 assert_equal(dtnat + 3, dtnat) 1010 assert_equal((dta + 3).dtype, np.dtype('M8[D]')) 1011 # bool + M8 1012 assert_equal(False + dta, dta) 1013 assert_equal(False + dtnat, dtnat) 1014 assert_equal((False + dta).dtype, np.dtype('M8[D]')) 1015 # int + M8 1016 assert_equal(3 + dta, dtb) 1017 assert_equal(3 + dtnat, dtnat) 1018 assert_equal((3 + dta).dtype, np.dtype('M8[D]')) 1019 # M8 + m8 1020 assert_equal(dta + tda, dtb) 1021 assert_equal(dtnat + tda, dtnat) 1022 assert_equal((dta + tda).dtype, np.dtype('M8[D]')) 1023 # m8 + M8 1024 assert_equal(tda + dta, dtb) 1025 assert_equal(tda + dtnat, dtnat) 1026 assert_equal((tda + dta).dtype, np.dtype('M8[D]')) 1027 1028 # In M8 + m8, the result goes to higher precision 1029 assert_equal(np.add(dta, tdb, casting='unsafe'), dtc) 1030 assert_equal(np.add(dta, tdb, casting='unsafe').dtype, 1031 np.dtype('M8[h]')) 1032 assert_equal(np.add(tdb, dta, casting='unsafe'), dtc) 1033 assert_equal(np.add(tdb, dta, casting='unsafe').dtype, 1034 np.dtype('M8[h]')) 1035 1036 # M8 + M8 1037 assert_raises(TypeError, np.add, dta, dtb) 1038 1039 def test_datetime_subtract(self): 1040 for dta, dtb, dtc, dtd, dte, dtnat, tda, tdb, tdc in \ 1041 [ 1042 # One-dimensional arrays 1043 (np.array(['2012-12-21'], dtype='M8[D]'), 1044 np.array(['2012-12-24'], dtype='M8[D]'), 1045 np.array(['1940-12-24'], dtype='M8[D]'), 1046 np.array(['1940-12-24T00'], dtype='M8[h]'), 1047 np.array(['1940-12-23T13'], dtype='M8[h]'), 1048 np.array(['NaT'], dtype='M8[D]'), 1049 np.array([3], dtype='m8[D]'), 1050 np.array([11], dtype='m8[h]'), 1051 np.array([3*24 - 11], dtype='m8[h]')), 1052 # NumPy scalars 1053 (np.datetime64('2012-12-21', '[D]'), 1054 np.datetime64('2012-12-24', '[D]'), 1055 np.datetime64('1940-12-24', '[D]'), 1056 np.datetime64('1940-12-24T00', '[h]'), 1057 np.datetime64('1940-12-23T13', '[h]'), 1058 np.datetime64('NaT', '[D]'), 1059 np.timedelta64(3, '[D]'), 1060 np.timedelta64(11, '[h]'), 1061 np.timedelta64(3*24 - 11, '[h]'))]: 1062 # m8 - m8 1063 assert_equal(tda - tdb, tdc) 1064 assert_equal((tda - tdb).dtype, np.dtype('m8[h]')) 1065 assert_equal(tdb - tda, -tdc) 1066 assert_equal((tdb - tda).dtype, np.dtype('m8[h]')) 1067 # m8 - bool 1068 assert_equal(tdc - True, tdc - 1) 1069 assert_equal((tdc - True).dtype, np.dtype('m8[h]')) 1070 # m8 - int 1071 assert_equal(tdc - 3*24, -tdb) 1072 assert_equal((tdc - 3*24).dtype, np.dtype('m8[h]')) 1073 # int - m8 1074 assert_equal(False - tdb, -tdb) 1075 assert_equal((False - tdb).dtype, np.dtype('m8[h]')) 1076 # int - m8 1077 assert_equal(3*24 - tdb, tdc) 1078 assert_equal((3*24 - tdb).dtype, np.dtype('m8[h]')) 1079 # M8 - bool 1080 assert_equal(dtb - True, dtb - 1) 1081 assert_equal(dtnat - True, dtnat) 1082 assert_equal((dtb - True).dtype, np.dtype('M8[D]')) 1083 # M8 - int 1084 assert_equal(dtb - 3, dta) 1085 assert_equal(dtnat - 3, dtnat) 1086 assert_equal((dtb - 3).dtype, np.dtype('M8[D]')) 1087 # M8 - m8 1088 assert_equal(dtb - tda, dta) 1089 assert_equal(dtnat - tda, dtnat) 1090 assert_equal((dtb - tda).dtype, np.dtype('M8[D]')) 1091 1092 # In M8 - m8, the result goes to higher precision 1093 assert_equal(np.subtract(dtc, tdb, casting='unsafe'), dte) 1094 assert_equal(np.subtract(dtc, tdb, casting='unsafe').dtype, 1095 np.dtype('M8[h]')) 1096 1097 # M8 - M8 with different goes to higher precision 1098 assert_equal(np.subtract(dtc, dtd, casting='unsafe'), 1099 np.timedelta64(0, 'h')) 1100 assert_equal(np.subtract(dtc, dtd, casting='unsafe').dtype, 1101 np.dtype('m8[h]')) 1102 assert_equal(np.subtract(dtd, dtc, casting='unsafe'), 1103 np.timedelta64(0, 'h')) 1104 assert_equal(np.subtract(dtd, dtc, casting='unsafe').dtype, 1105 np.dtype('m8[h]')) 1106 1107 # m8 - M8 1108 assert_raises(TypeError, np.subtract, tda, dta) 1109 # bool - M8 1110 assert_raises(TypeError, np.subtract, False, dta) 1111 # int - M8 1112 assert_raises(TypeError, np.subtract, 3, dta) 1113 1114 def test_datetime_multiply(self): 1115 for dta, tda, tdb, tdc in \ 1116 [ 1117 # One-dimensional arrays 1118 (np.array(['2012-12-21'], dtype='M8[D]'), 1119 np.array([6], dtype='m8[h]'), 1120 np.array([9], dtype='m8[h]'), 1121 np.array([12], dtype='m8[h]')), 1122 # NumPy scalars 1123 (np.datetime64('2012-12-21', '[D]'), 1124 np.timedelta64(6, '[h]'), 1125 np.timedelta64(9, '[h]'), 1126 np.timedelta64(12, '[h]'))]: 1127 # m8 * int 1128 assert_equal(tda * 2, tdc) 1129 assert_equal((tda * 2).dtype, np.dtype('m8[h]')) 1130 # int * m8 1131 assert_equal(2 * tda, tdc) 1132 assert_equal((2 * tda).dtype, np.dtype('m8[h]')) 1133 # m8 * float 1134 assert_equal(tda * 1.5, tdb) 1135 assert_equal((tda * 1.5).dtype, np.dtype('m8[h]')) 1136 # float * m8 1137 assert_equal(1.5 * tda, tdb) 1138 assert_equal((1.5 * tda).dtype, np.dtype('m8[h]')) 1139 1140 # m8 * m8 1141 assert_raises(TypeError, np.multiply, tda, tdb) 1142 # m8 * M8 1143 assert_raises(TypeError, np.multiply, dta, tda) 1144 # M8 * m8 1145 assert_raises(TypeError, np.multiply, tda, dta) 1146 # M8 * int 1147 assert_raises(TypeError, np.multiply, dta, 2) 1148 # int * M8 1149 assert_raises(TypeError, np.multiply, 2, dta) 1150 # M8 * float 1151 assert_raises(TypeError, np.multiply, dta, 1.5) 1152 # float * M8 1153 assert_raises(TypeError, np.multiply, 1.5, dta) 1154 1155 # NaTs 1156 with suppress_warnings() as sup: 1157 sup.filter(RuntimeWarning, "invalid value encountered in multiply") 1158 nat = np.timedelta64('NaT') 1159 def check(a, b, res): 1160 assert_equal(a * b, res) 1161 assert_equal(b * a, res) 1162 for tp in (int, float): 1163 check(nat, tp(2), nat) 1164 check(nat, tp(0), nat) 1165 for f in (float('inf'), float('nan')): 1166 check(np.timedelta64(1), f, nat) 1167 check(np.timedelta64(0), f, nat) 1168 check(nat, f, nat) 1169 1170 @pytest.mark.parametrize("op1, op2, exp", [ 1171 # m8 same units round down 1172 (np.timedelta64(7, 's'), 1173 np.timedelta64(4, 's'), 1174 1), 1175 # m8 same units round down with negative 1176 (np.timedelta64(7, 's'), 1177 np.timedelta64(-4, 's'), 1178 -2), 1179 # m8 same units negative no round down 1180 (np.timedelta64(8, 's'), 1181 np.timedelta64(-4, 's'), 1182 -2), 1183 # m8 different units 1184 (np.timedelta64(1, 'm'), 1185 np.timedelta64(31, 's'), 1186 1), 1187 # m8 generic units 1188 (np.timedelta64(1890), 1189 np.timedelta64(31), 1190 60), 1191 # Y // M works 1192 (np.timedelta64(2, 'Y'), 1193 np.timedelta64('13', 'M'), 1194 1), 1195 # handle 1D arrays 1196 (np.array([1, 2, 3], dtype='m8'), 1197 np.array([2], dtype='m8'), 1198 np.array([0, 1, 1], dtype=np.int64)), 1199 ]) 1200 def test_timedelta_floor_divide(self, op1, op2, exp): 1201 assert_equal(op1 // op2, exp) 1202 1203 @pytest.mark.parametrize("op1, op2", [ 1204 # div by 0 1205 (np.timedelta64(10, 'us'), 1206 np.timedelta64(0, 'us')), 1207 # div with NaT 1208 (np.timedelta64('NaT'), 1209 np.timedelta64(50, 'us')), 1210 # special case for int64 min 1211 # in integer floor division 1212 (np.timedelta64(np.iinfo(np.int64).min), 1213 np.timedelta64(-1)), 1214 ]) 1215 def test_timedelta_floor_div_warnings(self, op1, op2): 1216 with assert_warns(RuntimeWarning): 1217 actual = op1 // op2 1218 assert_equal(actual, 0) 1219 assert_equal(actual.dtype, np.int64) 1220 1221 @pytest.mark.parametrize("val1, val2", [ 1222 # the smallest integer that can't be represented 1223 # exactly in a double should be preserved if we avoid 1224 # casting to double in floordiv operation 1225 (9007199254740993, 1), 1226 # stress the alternate floordiv code path where 1227 # operand signs don't match and remainder isn't 0 1228 (9007199254740999, -2), 1229 ]) 1230 def test_timedelta_floor_div_precision(self, val1, val2): 1231 op1 = np.timedelta64(val1) 1232 op2 = np.timedelta64(val2) 1233 actual = op1 // op2 1234 # Python reference integer floor 1235 expected = val1 // val2 1236 assert_equal(actual, expected) 1237 1238 @pytest.mark.parametrize("val1, val2", [ 1239 # years and months sometimes can't be unambiguously 1240 # divided for floor division operation 1241 (np.timedelta64(7, 'Y'), 1242 np.timedelta64(3, 's')), 1243 (np.timedelta64(7, 'M'), 1244 np.timedelta64(1, 'D')), 1245 ]) 1246 def test_timedelta_floor_div_error(self, val1, val2): 1247 with assert_raises_regex(TypeError, "common metadata divisor"): 1248 val1 // val2 1249 1250 @pytest.mark.parametrize("op1, op2", [ 1251 # reuse the test cases from floordiv 1252 (np.timedelta64(7, 's'), 1253 np.timedelta64(4, 's')), 1254 # m8 same units round down with negative 1255 (np.timedelta64(7, 's'), 1256 np.timedelta64(-4, 's')), 1257 # m8 same units negative no round down 1258 (np.timedelta64(8, 's'), 1259 np.timedelta64(-4, 's')), 1260 # m8 different units 1261 (np.timedelta64(1, 'm'), 1262 np.timedelta64(31, 's')), 1263 # m8 generic units 1264 (np.timedelta64(1890), 1265 np.timedelta64(31)), 1266 # Y // M works 1267 (np.timedelta64(2, 'Y'), 1268 np.timedelta64('13', 'M')), 1269 # handle 1D arrays 1270 (np.array([1, 2, 3], dtype='m8'), 1271 np.array([2], dtype='m8')), 1272 ]) 1273 def test_timedelta_divmod(self, op1, op2): 1274 expected = (op1 // op2, op1 % op2) 1275 assert_equal(divmod(op1, op2), expected) 1276 1277 @pytest.mark.parametrize("op1, op2", [ 1278 # reuse cases from floordiv 1279 # div by 0 1280 (np.timedelta64(10, 'us'), 1281 np.timedelta64(0, 'us')), 1282 # div with NaT 1283 (np.timedelta64('NaT'), 1284 np.timedelta64(50, 'us')), 1285 # special case for int64 min 1286 # in integer floor division 1287 (np.timedelta64(np.iinfo(np.int64).min), 1288 np.timedelta64(-1)), 1289 ]) 1290 def test_timedelta_divmod_warnings(self, op1, op2): 1291 with assert_warns(RuntimeWarning): 1292 expected = (op1 // op2, op1 % op2) 1293 with assert_warns(RuntimeWarning): 1294 actual = divmod(op1, op2) 1295 assert_equal(actual, expected) 1296 1297 def test_datetime_divide(self): 1298 for dta, tda, tdb, tdc, tdd in \ 1299 [ 1300 # One-dimensional arrays 1301 (np.array(['2012-12-21'], dtype='M8[D]'), 1302 np.array([6], dtype='m8[h]'), 1303 np.array([9], dtype='m8[h]'), 1304 np.array([12], dtype='m8[h]'), 1305 np.array([6], dtype='m8[m]')), 1306 # NumPy scalars 1307 (np.datetime64('2012-12-21', '[D]'), 1308 np.timedelta64(6, '[h]'), 1309 np.timedelta64(9, '[h]'), 1310 np.timedelta64(12, '[h]'), 1311 np.timedelta64(6, '[m]'))]: 1312 # m8 / int 1313 assert_equal(tdc / 2, tda) 1314 assert_equal((tdc / 2).dtype, np.dtype('m8[h]')) 1315 # m8 / float 1316 assert_equal(tda / 0.5, tdc) 1317 assert_equal((tda / 0.5).dtype, np.dtype('m8[h]')) 1318 # m8 / m8 1319 assert_equal(tda / tdb, 6.0 / 9.0) 1320 assert_equal(np.divide(tda, tdb), 6.0 / 9.0) 1321 assert_equal(np.true_divide(tda, tdb), 6.0 / 9.0) 1322 assert_equal(tdb / tda, 9.0 / 6.0) 1323 assert_equal((tda / tdb).dtype, np.dtype('f8')) 1324 assert_equal(tda / tdd, 60.0) 1325 assert_equal(tdd / tda, 1.0 / 60.0) 1326 1327 # int / m8 1328 assert_raises(TypeError, np.divide, 2, tdb) 1329 # float / m8 1330 assert_raises(TypeError, np.divide, 0.5, tdb) 1331 # m8 / M8 1332 assert_raises(TypeError, np.divide, dta, tda) 1333 # M8 / m8 1334 assert_raises(TypeError, np.divide, tda, dta) 1335 # M8 / int 1336 assert_raises(TypeError, np.divide, dta, 2) 1337 # int / M8 1338 assert_raises(TypeError, np.divide, 2, dta) 1339 # M8 / float 1340 assert_raises(TypeError, np.divide, dta, 1.5) 1341 # float / M8 1342 assert_raises(TypeError, np.divide, 1.5, dta) 1343 1344 # NaTs 1345 with suppress_warnings() as sup: 1346 sup.filter(RuntimeWarning, r".*encountered in true\_divide") 1347 nat = np.timedelta64('NaT') 1348 for tp in (int, float): 1349 assert_equal(np.timedelta64(1) / tp(0), nat) 1350 assert_equal(np.timedelta64(0) / tp(0), nat) 1351 assert_equal(nat / tp(0), nat) 1352 assert_equal(nat / tp(2), nat) 1353 # Division by inf 1354 assert_equal(np.timedelta64(1) / float('inf'), np.timedelta64(0)) 1355 assert_equal(np.timedelta64(0) / float('inf'), np.timedelta64(0)) 1356 assert_equal(nat / float('inf'), nat) 1357 # Division by nan 1358 assert_equal(np.timedelta64(1) / float('nan'), nat) 1359 assert_equal(np.timedelta64(0) / float('nan'), nat) 1360 assert_equal(nat / float('nan'), nat) 1361 1362 def test_datetime_compare(self): 1363 # Test all the comparison operators 1364 a = np.datetime64('2000-03-12T18:00:00.000000') 1365 b = np.array(['2000-03-12T18:00:00.000000', 1366 '2000-03-12T17:59:59.999999', 1367 '2000-03-12T18:00:00.000001', 1368 '1970-01-11T12:00:00.909090', 1369 '2016-01-11T12:00:00.909090'], 1370 dtype='datetime64[us]') 1371 assert_equal(np.equal(a, b), [1, 0, 0, 0, 0]) 1372 assert_equal(np.not_equal(a, b), [0, 1, 1, 1, 1]) 1373 assert_equal(np.less(a, b), [0, 0, 1, 0, 1]) 1374 assert_equal(np.less_equal(a, b), [1, 0, 1, 0, 1]) 1375 assert_equal(np.greater(a, b), [0, 1, 0, 1, 0]) 1376 assert_equal(np.greater_equal(a, b), [1, 1, 0, 1, 0]) 1377 1378 def test_datetime_compare_nat(self): 1379 dt_nat = np.datetime64('NaT', 'D') 1380 dt_other = np.datetime64('2000-01-01') 1381 td_nat = np.timedelta64('NaT', 'h') 1382 td_other = np.timedelta64(1, 'h') 1383 1384 for op in [np.equal, np.less, np.less_equal, 1385 np.greater, np.greater_equal]: 1386 assert_(not op(dt_nat, dt_nat)) 1387 assert_(not op(dt_nat, dt_other)) 1388 assert_(not op(dt_other, dt_nat)) 1389 1390 assert_(not op(td_nat, td_nat)) 1391 assert_(not op(td_nat, td_other)) 1392 assert_(not op(td_other, td_nat)) 1393 1394 assert_(np.not_equal(dt_nat, dt_nat)) 1395 assert_(np.not_equal(dt_nat, dt_other)) 1396 assert_(np.not_equal(dt_other, dt_nat)) 1397 1398 assert_(np.not_equal(td_nat, td_nat)) 1399 assert_(np.not_equal(td_nat, td_other)) 1400 assert_(np.not_equal(td_other, td_nat)) 1401 1402 def test_datetime_minmax(self): 1403 # The metadata of the result should become the GCD 1404 # of the operand metadata 1405 a = np.array('1999-03-12T13', dtype='M8[2m]') 1406 b = np.array('1999-03-12T12', dtype='M8[s]') 1407 assert_equal(np.minimum(a, b), b) 1408 assert_equal(np.minimum(a, b).dtype, np.dtype('M8[s]')) 1409 assert_equal(np.fmin(a, b), b) 1410 assert_equal(np.fmin(a, b).dtype, np.dtype('M8[s]')) 1411 assert_equal(np.maximum(a, b), a) 1412 assert_equal(np.maximum(a, b).dtype, np.dtype('M8[s]')) 1413 assert_equal(np.fmax(a, b), a) 1414 assert_equal(np.fmax(a, b).dtype, np.dtype('M8[s]')) 1415 # Viewed as integers, the comparison is opposite because 1416 # of the units chosen 1417 assert_equal(np.minimum(a.view('i8'), b.view('i8')), a.view('i8')) 1418 1419 # Interaction with NaT 1420 a = np.array('1999-03-12T13', dtype='M8[2m]') 1421 dtnat = np.array('NaT', dtype='M8[h]') 1422 assert_equal(np.minimum(a, dtnat), dtnat) 1423 assert_equal(np.minimum(dtnat, a), dtnat) 1424 assert_equal(np.maximum(a, dtnat), dtnat) 1425 assert_equal(np.maximum(dtnat, a), dtnat) 1426 assert_equal(np.fmin(dtnat, a), a) 1427 assert_equal(np.fmin(a, dtnat), a) 1428 assert_equal(np.fmax(dtnat, a), a) 1429 assert_equal(np.fmax(a, dtnat), a) 1430 1431 # Also do timedelta 1432 a = np.array(3, dtype='m8[h]') 1433 b = np.array(3*3600 - 3, dtype='m8[s]') 1434 assert_equal(np.minimum(a, b), b) 1435 assert_equal(np.minimum(a, b).dtype, np.dtype('m8[s]')) 1436 assert_equal(np.fmin(a, b), b) 1437 assert_equal(np.fmin(a, b).dtype, np.dtype('m8[s]')) 1438 assert_equal(np.maximum(a, b), a) 1439 assert_equal(np.maximum(a, b).dtype, np.dtype('m8[s]')) 1440 assert_equal(np.fmax(a, b), a) 1441 assert_equal(np.fmax(a, b).dtype, np.dtype('m8[s]')) 1442 # Viewed as integers, the comparison is opposite because 1443 # of the units chosen 1444 assert_equal(np.minimum(a.view('i8'), b.view('i8')), a.view('i8')) 1445 1446 # should raise between datetime and timedelta 1447 # 1448 # TODO: Allowing unsafe casting by 1449 # default in ufuncs strikes again... :( 1450 a = np.array(3, dtype='m8[h]') 1451 b = np.array('1999-03-12T12', dtype='M8[s]') 1452 #assert_raises(TypeError, np.minimum, a, b) 1453 #assert_raises(TypeError, np.maximum, a, b) 1454 #assert_raises(TypeError, np.fmin, a, b) 1455 #assert_raises(TypeError, np.fmax, a, b) 1456 assert_raises(TypeError, np.minimum, a, b, casting='same_kind') 1457 assert_raises(TypeError, np.maximum, a, b, casting='same_kind') 1458 assert_raises(TypeError, np.fmin, a, b, casting='same_kind') 1459 assert_raises(TypeError, np.fmax, a, b, casting='same_kind') 1460 1461 def test_hours(self): 1462 t = np.ones(3, dtype='M8[s]') 1463 t[0] = 60*60*24 + 60*60*10 1464 assert_(t[0].item().hour == 10) 1465 1466 def test_divisor_conversion_year(self): 1467 assert_(np.dtype('M8[Y/4]') == np.dtype('M8[3M]')) 1468 assert_(np.dtype('M8[Y/13]') == np.dtype('M8[4W]')) 1469 assert_(np.dtype('M8[3Y/73]') == np.dtype('M8[15D]')) 1470 1471 def test_divisor_conversion_month(self): 1472 assert_(np.dtype('M8[M/2]') == np.dtype('M8[2W]')) 1473 assert_(np.dtype('M8[M/15]') == np.dtype('M8[2D]')) 1474 assert_(np.dtype('M8[3M/40]') == np.dtype('M8[54h]')) 1475 1476 def test_divisor_conversion_week(self): 1477 assert_(np.dtype('m8[W/7]') == np.dtype('m8[D]')) 1478 assert_(np.dtype('m8[3W/14]') == np.dtype('m8[36h]')) 1479 assert_(np.dtype('m8[5W/140]') == np.dtype('m8[360m]')) 1480 1481 def test_divisor_conversion_day(self): 1482 assert_(np.dtype('M8[D/12]') == np.dtype('M8[2h]')) 1483 assert_(np.dtype('M8[D/120]') == np.dtype('M8[12m]')) 1484 assert_(np.dtype('M8[3D/960]') == np.dtype('M8[270s]')) 1485 1486 def test_divisor_conversion_hour(self): 1487 assert_(np.dtype('m8[h/30]') == np.dtype('m8[2m]')) 1488 assert_(np.dtype('m8[3h/300]') == np.dtype('m8[36s]')) 1489 1490 def test_divisor_conversion_minute(self): 1491 assert_(np.dtype('m8[m/30]') == np.dtype('m8[2s]')) 1492 assert_(np.dtype('m8[3m/300]') == np.dtype('m8[600ms]')) 1493 1494 def test_divisor_conversion_second(self): 1495 assert_(np.dtype('m8[s/100]') == np.dtype('m8[10ms]')) 1496 assert_(np.dtype('m8[3s/10000]') == np.dtype('m8[300us]')) 1497 1498 def test_divisor_conversion_fs(self): 1499 assert_(np.dtype('M8[fs/100]') == np.dtype('M8[10as]')) 1500 assert_raises(ValueError, lambda: np.dtype('M8[3fs/10000]')) 1501 1502 def test_divisor_conversion_as(self): 1503 assert_raises(ValueError, lambda: np.dtype('M8[as/10]')) 1504 1505 def test_string_parser_variants(self): 1506 # Allow space instead of 'T' between date and time 1507 assert_equal(np.array(['1980-02-29T01:02:03'], np.dtype('M8[s]')), 1508 np.array(['1980-02-29 01:02:03'], np.dtype('M8[s]'))) 1509 # Allow positive years 1510 assert_equal(np.array(['+1980-02-29T01:02:03'], np.dtype('M8[s]')), 1511 np.array(['+1980-02-29 01:02:03'], np.dtype('M8[s]'))) 1512 # Allow negative years 1513 assert_equal(np.array(['-1980-02-29T01:02:03'], np.dtype('M8[s]')), 1514 np.array(['-1980-02-29 01:02:03'], np.dtype('M8[s]'))) 1515 # UTC specifier 1516 with assert_warns(DeprecationWarning): 1517 assert_equal( 1518 np.array(['+1980-02-29T01:02:03'], np.dtype('M8[s]')), 1519 np.array(['+1980-02-29 01:02:03Z'], np.dtype('M8[s]'))) 1520 with assert_warns(DeprecationWarning): 1521 assert_equal( 1522 np.array(['-1980-02-29T01:02:03'], np.dtype('M8[s]')), 1523 np.array(['-1980-02-29 01:02:03Z'], np.dtype('M8[s]'))) 1524 # Time zone offset 1525 with assert_warns(DeprecationWarning): 1526 assert_equal( 1527 np.array(['1980-02-29T02:02:03'], np.dtype('M8[s]')), 1528 np.array(['1980-02-29 00:32:03-0130'], np.dtype('M8[s]'))) 1529 with assert_warns(DeprecationWarning): 1530 assert_equal( 1531 np.array(['1980-02-28T22:32:03'], np.dtype('M8[s]')), 1532 np.array(['1980-02-29 00:02:03+01:30'], np.dtype('M8[s]'))) 1533 with assert_warns(DeprecationWarning): 1534 assert_equal( 1535 np.array(['1980-02-29T02:32:03.506'], np.dtype('M8[s]')), 1536 np.array(['1980-02-29 00:32:03.506-02'], np.dtype('M8[s]'))) 1537 with assert_warns(DeprecationWarning): 1538 assert_equal(np.datetime64('1977-03-02T12:30-0230'), 1539 np.datetime64('1977-03-02T15:00')) 1540 1541 def test_string_parser_error_check(self): 1542 # Arbitrary bad string 1543 assert_raises(ValueError, np.array, ['badvalue'], np.dtype('M8[us]')) 1544 # Character after year must be '-' 1545 assert_raises(ValueError, np.array, ['1980X'], np.dtype('M8[us]')) 1546 # Cannot have trailing '-' 1547 assert_raises(ValueError, np.array, ['1980-'], np.dtype('M8[us]')) 1548 # Month must be in range [1,12] 1549 assert_raises(ValueError, np.array, ['1980-00'], np.dtype('M8[us]')) 1550 assert_raises(ValueError, np.array, ['1980-13'], np.dtype('M8[us]')) 1551 # Month must have two digits 1552 assert_raises(ValueError, np.array, ['1980-1'], np.dtype('M8[us]')) 1553 assert_raises(ValueError, np.array, ['1980-1-02'], np.dtype('M8[us]')) 1554 # 'Mor' is not a valid month 1555 assert_raises(ValueError, np.array, ['1980-Mor'], np.dtype('M8[us]')) 1556 # Cannot have trailing '-' 1557 assert_raises(ValueError, np.array, ['1980-01-'], np.dtype('M8[us]')) 1558 # Day must be in range [1,len(month)] 1559 assert_raises(ValueError, np.array, ['1980-01-0'], np.dtype('M8[us]')) 1560 assert_raises(ValueError, np.array, ['1980-01-00'], np.dtype('M8[us]')) 1561 assert_raises(ValueError, np.array, ['1980-01-32'], np.dtype('M8[us]')) 1562 assert_raises(ValueError, np.array, ['1979-02-29'], np.dtype('M8[us]')) 1563 assert_raises(ValueError, np.array, ['1980-02-30'], np.dtype('M8[us]')) 1564 assert_raises(ValueError, np.array, ['1980-03-32'], np.dtype('M8[us]')) 1565 assert_raises(ValueError, np.array, ['1980-04-31'], np.dtype('M8[us]')) 1566 assert_raises(ValueError, np.array, ['1980-05-32'], np.dtype('M8[us]')) 1567 assert_raises(ValueError, np.array, ['1980-06-31'], np.dtype('M8[us]')) 1568 assert_raises(ValueError, np.array, ['1980-07-32'], np.dtype('M8[us]')) 1569 assert_raises(ValueError, np.array, ['1980-08-32'], np.dtype('M8[us]')) 1570 assert_raises(ValueError, np.array, ['1980-09-31'], np.dtype('M8[us]')) 1571 assert_raises(ValueError, np.array, ['1980-10-32'], np.dtype('M8[us]')) 1572 assert_raises(ValueError, np.array, ['1980-11-31'], np.dtype('M8[us]')) 1573 assert_raises(ValueError, np.array, ['1980-12-32'], np.dtype('M8[us]')) 1574 # Cannot have trailing characters 1575 assert_raises(ValueError, np.array, ['1980-02-03%'], 1576 np.dtype('M8[us]')) 1577 assert_raises(ValueError, np.array, ['1980-02-03 q'], 1578 np.dtype('M8[us]')) 1579 1580 # Hours must be in range [0, 23] 1581 assert_raises(ValueError, np.array, ['1980-02-03 25'], 1582 np.dtype('M8[us]')) 1583 assert_raises(ValueError, np.array, ['1980-02-03T25'], 1584 np.dtype('M8[us]')) 1585 assert_raises(ValueError, np.array, ['1980-02-03 24:01'], 1586 np.dtype('M8[us]')) 1587 assert_raises(ValueError, np.array, ['1980-02-03T24:01'], 1588 np.dtype('M8[us]')) 1589 assert_raises(ValueError, np.array, ['1980-02-03 -1'], 1590 np.dtype('M8[us]')) 1591 # No trailing ':' 1592 assert_raises(ValueError, np.array, ['1980-02-03 01:'], 1593 np.dtype('M8[us]')) 1594 # Minutes must be in range [0, 59] 1595 assert_raises(ValueError, np.array, ['1980-02-03 01:-1'], 1596 np.dtype('M8[us]')) 1597 assert_raises(ValueError, np.array, ['1980-02-03 01:60'], 1598 np.dtype('M8[us]')) 1599 # No trailing ':' 1600 assert_raises(ValueError, np.array, ['1980-02-03 01:60:'], 1601 np.dtype('M8[us]')) 1602 # Seconds must be in range [0, 59] 1603 assert_raises(ValueError, np.array, ['1980-02-03 01:10:-1'], 1604 np.dtype('M8[us]')) 1605 assert_raises(ValueError, np.array, ['1980-02-03 01:01:60'], 1606 np.dtype('M8[us]')) 1607 # Timezone offset must within a reasonable range 1608 with assert_warns(DeprecationWarning): 1609 assert_raises(ValueError, np.array, ['1980-02-03 01:01:00+0661'], 1610 np.dtype('M8[us]')) 1611 with assert_warns(DeprecationWarning): 1612 assert_raises(ValueError, np.array, ['1980-02-03 01:01:00+2500'], 1613 np.dtype('M8[us]')) 1614 with assert_warns(DeprecationWarning): 1615 assert_raises(ValueError, np.array, ['1980-02-03 01:01:00-0070'], 1616 np.dtype('M8[us]')) 1617 with assert_warns(DeprecationWarning): 1618 assert_raises(ValueError, np.array, ['1980-02-03 01:01:00-3000'], 1619 np.dtype('M8[us]')) 1620 with assert_warns(DeprecationWarning): 1621 assert_raises(ValueError, np.array, ['1980-02-03 01:01:00-25:00'], 1622 np.dtype('M8[us]')) 1623 1624 def test_creation_overflow(self): 1625 date = '1980-03-23 20:00:00' 1626 timesteps = np.array([date], dtype='datetime64[s]')[0].astype(np.int64) 1627 for unit in ['ms', 'us', 'ns']: 1628 timesteps *= 1000 1629 x = np.array([date], dtype='datetime64[%s]' % unit) 1630 1631 assert_equal(timesteps, x[0].astype(np.int64), 1632 err_msg='Datetime conversion error for unit %s' % unit) 1633 1634 assert_equal(x[0].astype(np.int64), 322689600000000000) 1635 1636 # gh-13062 1637 with pytest.raises(OverflowError): 1638 np.datetime64(2**64, 'D') 1639 with pytest.raises(OverflowError): 1640 np.timedelta64(2**64, 'D') 1641 1642 def test_datetime_as_string(self): 1643 # Check all the units with default string conversion 1644 date = '1959-10-13' 1645 datetime = '1959-10-13T12:34:56.789012345678901234' 1646 1647 assert_equal(np.datetime_as_string(np.datetime64(date, 'Y')), 1648 '1959') 1649 assert_equal(np.datetime_as_string(np.datetime64(date, 'M')), 1650 '1959-10') 1651 assert_equal(np.datetime_as_string(np.datetime64(date, 'D')), 1652 '1959-10-13') 1653 assert_equal(np.datetime_as_string(np.datetime64(datetime, 'h')), 1654 '1959-10-13T12') 1655 assert_equal(np.datetime_as_string(np.datetime64(datetime, 'm')), 1656 '1959-10-13T12:34') 1657 assert_equal(np.datetime_as_string(np.datetime64(datetime, 's')), 1658 '1959-10-13T12:34:56') 1659 assert_equal(np.datetime_as_string(np.datetime64(datetime, 'ms')), 1660 '1959-10-13T12:34:56.789') 1661 for us in ['us', 'μs', b'us']: # check non-ascii and bytes too 1662 assert_equal(np.datetime_as_string(np.datetime64(datetime, us)), 1663 '1959-10-13T12:34:56.789012') 1664 1665 datetime = '1969-12-31T23:34:56.789012345678901234' 1666 1667 assert_equal(np.datetime_as_string(np.datetime64(datetime, 'ns')), 1668 '1969-12-31T23:34:56.789012345') 1669 assert_equal(np.datetime_as_string(np.datetime64(datetime, 'ps')), 1670 '1969-12-31T23:34:56.789012345678') 1671 assert_equal(np.datetime_as_string(np.datetime64(datetime, 'fs')), 1672 '1969-12-31T23:34:56.789012345678901') 1673 1674 datetime = '1969-12-31T23:59:57.789012345678901234' 1675 1676 assert_equal(np.datetime_as_string(np.datetime64(datetime, 'as')), 1677 datetime) 1678 datetime = '1970-01-01T00:34:56.789012345678901234' 1679 1680 assert_equal(np.datetime_as_string(np.datetime64(datetime, 'ns')), 1681 '1970-01-01T00:34:56.789012345') 1682 assert_equal(np.datetime_as_string(np.datetime64(datetime, 'ps')), 1683 '1970-01-01T00:34:56.789012345678') 1684 assert_equal(np.datetime_as_string(np.datetime64(datetime, 'fs')), 1685 '1970-01-01T00:34:56.789012345678901') 1686 1687 datetime = '1970-01-01T00:00:05.789012345678901234' 1688 1689 assert_equal(np.datetime_as_string(np.datetime64(datetime, 'as')), 1690 datetime) 1691 1692 # String conversion with the unit= parameter 1693 a = np.datetime64('2032-07-18T12:23:34.123456', 'us') 1694 assert_equal(np.datetime_as_string(a, unit='Y', casting='unsafe'), 1695 '2032') 1696 assert_equal(np.datetime_as_string(a, unit='M', casting='unsafe'), 1697 '2032-07') 1698 assert_equal(np.datetime_as_string(a, unit='W', casting='unsafe'), 1699 '2032-07-18') 1700 assert_equal(np.datetime_as_string(a, unit='D', casting='unsafe'), 1701 '2032-07-18') 1702 assert_equal(np.datetime_as_string(a, unit='h'), '2032-07-18T12') 1703 assert_equal(np.datetime_as_string(a, unit='m'), 1704 '2032-07-18T12:23') 1705 assert_equal(np.datetime_as_string(a, unit='s'), 1706 '2032-07-18T12:23:34') 1707 assert_equal(np.datetime_as_string(a, unit='ms'), 1708 '2032-07-18T12:23:34.123') 1709 assert_equal(np.datetime_as_string(a, unit='us'), 1710 '2032-07-18T12:23:34.123456') 1711 assert_equal(np.datetime_as_string(a, unit='ns'), 1712 '2032-07-18T12:23:34.123456000') 1713 assert_equal(np.datetime_as_string(a, unit='ps'), 1714 '2032-07-18T12:23:34.123456000000') 1715 assert_equal(np.datetime_as_string(a, unit='fs'), 1716 '2032-07-18T12:23:34.123456000000000') 1717 assert_equal(np.datetime_as_string(a, unit='as'), 1718 '2032-07-18T12:23:34.123456000000000000') 1719 1720 # unit='auto' parameter 1721 assert_equal(np.datetime_as_string( 1722 np.datetime64('2032-07-18T12:23:34.123456', 'us'), unit='auto'), 1723 '2032-07-18T12:23:34.123456') 1724 assert_equal(np.datetime_as_string( 1725 np.datetime64('2032-07-18T12:23:34.12', 'us'), unit='auto'), 1726 '2032-07-18T12:23:34.120') 1727 assert_equal(np.datetime_as_string( 1728 np.datetime64('2032-07-18T12:23:34', 'us'), unit='auto'), 1729 '2032-07-18T12:23:34') 1730 assert_equal(np.datetime_as_string( 1731 np.datetime64('2032-07-18T12:23:00', 'us'), unit='auto'), 1732 '2032-07-18T12:23') 1733 # 'auto' doesn't split up hour and minute 1734 assert_equal(np.datetime_as_string( 1735 np.datetime64('2032-07-18T12:00:00', 'us'), unit='auto'), 1736 '2032-07-18T12:00') 1737 assert_equal(np.datetime_as_string( 1738 np.datetime64('2032-07-18T00:00:00', 'us'), unit='auto'), 1739 '2032-07-18') 1740 # 'auto' doesn't split up the date 1741 assert_equal(np.datetime_as_string( 1742 np.datetime64('2032-07-01T00:00:00', 'us'), unit='auto'), 1743 '2032-07-01') 1744 assert_equal(np.datetime_as_string( 1745 np.datetime64('2032-01-01T00:00:00', 'us'), unit='auto'), 1746 '2032-01-01') 1747 1748 @pytest.mark.skipif(not _has_pytz, reason="The pytz module is not available.") 1749 def test_datetime_as_string_timezone(self): 1750 # timezone='local' vs 'UTC' 1751 a = np.datetime64('2010-03-15T06:30', 'm') 1752 assert_equal(np.datetime_as_string(a), 1753 '2010-03-15T06:30') 1754 assert_equal(np.datetime_as_string(a, timezone='naive'), 1755 '2010-03-15T06:30') 1756 assert_equal(np.datetime_as_string(a, timezone='UTC'), 1757 '2010-03-15T06:30Z') 1758 assert_(np.datetime_as_string(a, timezone='local') != 1759 '2010-03-15T06:30') 1760 1761 b = np.datetime64('2010-02-15T06:30', 'm') 1762 1763 assert_equal(np.datetime_as_string(a, timezone=tz('US/Central')), 1764 '2010-03-15T01:30-0500') 1765 assert_equal(np.datetime_as_string(a, timezone=tz('US/Eastern')), 1766 '2010-03-15T02:30-0400') 1767 assert_equal(np.datetime_as_string(a, timezone=tz('US/Pacific')), 1768 '2010-03-14T23:30-0700') 1769 1770 assert_equal(np.datetime_as_string(b, timezone=tz('US/Central')), 1771 '2010-02-15T00:30-0600') 1772 assert_equal(np.datetime_as_string(b, timezone=tz('US/Eastern')), 1773 '2010-02-15T01:30-0500') 1774 assert_equal(np.datetime_as_string(b, timezone=tz('US/Pacific')), 1775 '2010-02-14T22:30-0800') 1776 1777 # Dates to strings with a timezone attached is disabled by default 1778 assert_raises(TypeError, np.datetime_as_string, a, unit='D', 1779 timezone=tz('US/Pacific')) 1780 # Check that we can print out the date in the specified time zone 1781 assert_equal(np.datetime_as_string(a, unit='D', 1782 timezone=tz('US/Pacific'), casting='unsafe'), 1783 '2010-03-14') 1784 assert_equal(np.datetime_as_string(b, unit='D', 1785 timezone=tz('US/Central'), casting='unsafe'), 1786 '2010-02-15') 1787 1788 def test_datetime_arange(self): 1789 # With two datetimes provided as strings 1790 a = np.arange('2010-01-05', '2010-01-10', dtype='M8[D]') 1791 assert_equal(a.dtype, np.dtype('M8[D]')) 1792 assert_equal(a, 1793 np.array(['2010-01-05', '2010-01-06', '2010-01-07', 1794 '2010-01-08', '2010-01-09'], dtype='M8[D]')) 1795 1796 a = np.arange('1950-02-10', '1950-02-06', -1, dtype='M8[D]') 1797 assert_equal(a.dtype, np.dtype('M8[D]')) 1798 assert_equal(a, 1799 np.array(['1950-02-10', '1950-02-09', '1950-02-08', 1800 '1950-02-07'], dtype='M8[D]')) 1801 1802 # Unit should be detected as months here 1803 a = np.arange('1969-05', '1970-05', 2, dtype='M8') 1804 assert_equal(a.dtype, np.dtype('M8[M]')) 1805 assert_equal(a, 1806 np.datetime64('1969-05') + np.arange(12, step=2)) 1807 1808 # datetime, integer|timedelta works as well 1809 # produces arange (start, start + stop) in this case 1810 a = np.arange('1969', 18, 3, dtype='M8') 1811 assert_equal(a.dtype, np.dtype('M8[Y]')) 1812 assert_equal(a, 1813 np.datetime64('1969') + np.arange(18, step=3)) 1814 a = np.arange('1969-12-19', 22, np.timedelta64(2), dtype='M8') 1815 assert_equal(a.dtype, np.dtype('M8[D]')) 1816 assert_equal(a, 1817 np.datetime64('1969-12-19') + np.arange(22, step=2)) 1818 1819 # Step of 0 is disallowed 1820 assert_raises(ValueError, np.arange, np.datetime64('today'), 1821 np.datetime64('today') + 3, 0) 1822 # Promotion across nonlinear unit boundaries is disallowed 1823 assert_raises(TypeError, np.arange, np.datetime64('2011-03-01', 'D'), 1824 np.timedelta64(5, 'M')) 1825 assert_raises(TypeError, np.arange, 1826 np.datetime64('2012-02-03T14', 's'), 1827 np.timedelta64(5, 'Y')) 1828 1829 def test_datetime_arange_no_dtype(self): 1830 d = np.array('2010-01-04', dtype="M8[D]") 1831 assert_equal(np.arange(d, d + 1), d) 1832 assert_raises(ValueError, np.arange, d) 1833 1834 def test_timedelta_arange(self): 1835 a = np.arange(3, 10, dtype='m8') 1836 assert_equal(a.dtype, np.dtype('m8')) 1837 assert_equal(a, np.timedelta64(0) + np.arange(3, 10)) 1838 1839 a = np.arange(np.timedelta64(3, 's'), 10, 2, dtype='m8') 1840 assert_equal(a.dtype, np.dtype('m8[s]')) 1841 assert_equal(a, np.timedelta64(0, 's') + np.arange(3, 10, 2)) 1842 1843 # Step of 0 is disallowed 1844 assert_raises(ValueError, np.arange, np.timedelta64(0), 1845 np.timedelta64(5), 0) 1846 # Promotion across nonlinear unit boundaries is disallowed 1847 assert_raises(TypeError, np.arange, np.timedelta64(0, 'D'), 1848 np.timedelta64(5, 'M')) 1849 assert_raises(TypeError, np.arange, np.timedelta64(0, 'Y'), 1850 np.timedelta64(5, 'D')) 1851 1852 @pytest.mark.parametrize("val1, val2, expected", [ 1853 # case from gh-12092 1854 (np.timedelta64(7, 's'), 1855 np.timedelta64(3, 's'), 1856 np.timedelta64(1, 's')), 1857 # negative value cases 1858 (np.timedelta64(3, 's'), 1859 np.timedelta64(-2, 's'), 1860 np.timedelta64(-1, 's')), 1861 (np.timedelta64(-3, 's'), 1862 np.timedelta64(2, 's'), 1863 np.timedelta64(1, 's')), 1864 # larger value cases 1865 (np.timedelta64(17, 's'), 1866 np.timedelta64(22, 's'), 1867 np.timedelta64(17, 's')), 1868 (np.timedelta64(22, 's'), 1869 np.timedelta64(17, 's'), 1870 np.timedelta64(5, 's')), 1871 # different units 1872 (np.timedelta64(1, 'm'), 1873 np.timedelta64(57, 's'), 1874 np.timedelta64(3, 's')), 1875 (np.timedelta64(1, 'us'), 1876 np.timedelta64(727, 'ns'), 1877 np.timedelta64(273, 'ns')), 1878 # NaT is propagated 1879 (np.timedelta64('NaT'), 1880 np.timedelta64(50, 'ns'), 1881 np.timedelta64('NaT')), 1882 # Y % M works 1883 (np.timedelta64(2, 'Y'), 1884 np.timedelta64(22, 'M'), 1885 np.timedelta64(2, 'M')), 1886 ]) 1887 def test_timedelta_modulus(self, val1, val2, expected): 1888 assert_equal(val1 % val2, expected) 1889 1890 @pytest.mark.parametrize("val1, val2", [ 1891 # years and months sometimes can't be unambiguously 1892 # divided for modulus operation 1893 (np.timedelta64(7, 'Y'), 1894 np.timedelta64(3, 's')), 1895 (np.timedelta64(7, 'M'), 1896 np.timedelta64(1, 'D')), 1897 ]) 1898 def test_timedelta_modulus_error(self, val1, val2): 1899 with assert_raises_regex(TypeError, "common metadata divisor"): 1900 val1 % val2 1901 1902 def test_timedelta_modulus_div_by_zero(self): 1903 with assert_warns(RuntimeWarning): 1904 actual = np.timedelta64(10, 's') % np.timedelta64(0, 's') 1905 assert_equal(actual, np.timedelta64('NaT')) 1906 1907 @pytest.mark.parametrize("val1, val2", [ 1908 # cases where one operand is not 1909 # timedelta64 1910 (np.timedelta64(7, 'Y'), 1911 15,), 1912 (7.5, 1913 np.timedelta64(1, 'D')), 1914 ]) 1915 def test_timedelta_modulus_type_resolution(self, val1, val2): 1916 # NOTE: some of the operations may be supported 1917 # in the future 1918 with assert_raises_regex(TypeError, 1919 "'remainder' cannot use operands with types"): 1920 val1 % val2 1921 1922 def test_timedelta_arange_no_dtype(self): 1923 d = np.array(5, dtype="m8[D]") 1924 assert_equal(np.arange(d, d + 1), d) 1925 assert_equal(np.arange(d), np.arange(0, d)) 1926 1927 def test_datetime_maximum_reduce(self): 1928 a = np.array(['2010-01-02', '1999-03-14', '1833-03'], dtype='M8[D]') 1929 assert_equal(np.maximum.reduce(a).dtype, np.dtype('M8[D]')) 1930 assert_equal(np.maximum.reduce(a), 1931 np.datetime64('2010-01-02')) 1932 1933 a = np.array([1, 4, 0, 7, 2], dtype='m8[s]') 1934 assert_equal(np.maximum.reduce(a).dtype, np.dtype('m8[s]')) 1935 assert_equal(np.maximum.reduce(a), 1936 np.timedelta64(7, 's')) 1937 1938 def test_datetime_busday_offset(self): 1939 # First Monday in June 1940 assert_equal( 1941 np.busday_offset('2011-06', 0, roll='forward', weekmask='Mon'), 1942 np.datetime64('2011-06-06')) 1943 # Last Monday in June 1944 assert_equal( 1945 np.busday_offset('2011-07', -1, roll='forward', weekmask='Mon'), 1946 np.datetime64('2011-06-27')) 1947 assert_equal( 1948 np.busday_offset('2011-07', -1, roll='forward', weekmask='Mon'), 1949 np.datetime64('2011-06-27')) 1950 1951 # Default M-F business days, different roll modes 1952 assert_equal(np.busday_offset('2010-08', 0, roll='backward'), 1953 np.datetime64('2010-07-30')) 1954 assert_equal(np.busday_offset('2010-08', 0, roll='preceding'), 1955 np.datetime64('2010-07-30')) 1956 assert_equal(np.busday_offset('2010-08', 0, roll='modifiedpreceding'), 1957 np.datetime64('2010-08-02')) 1958 assert_equal(np.busday_offset('2010-08', 0, roll='modifiedfollowing'), 1959 np.datetime64('2010-08-02')) 1960 assert_equal(np.busday_offset('2010-08', 0, roll='forward'), 1961 np.datetime64('2010-08-02')) 1962 assert_equal(np.busday_offset('2010-08', 0, roll='following'), 1963 np.datetime64('2010-08-02')) 1964 assert_equal(np.busday_offset('2010-10-30', 0, roll='following'), 1965 np.datetime64('2010-11-01')) 1966 assert_equal( 1967 np.busday_offset('2010-10-30', 0, roll='modifiedfollowing'), 1968 np.datetime64('2010-10-29')) 1969 assert_equal( 1970 np.busday_offset('2010-10-30', 0, roll='modifiedpreceding'), 1971 np.datetime64('2010-10-29')) 1972 assert_equal( 1973 np.busday_offset('2010-10-16', 0, roll='modifiedfollowing'), 1974 np.datetime64('2010-10-18')) 1975 assert_equal( 1976 np.busday_offset('2010-10-16', 0, roll='modifiedpreceding'), 1977 np.datetime64('2010-10-15')) 1978 # roll='raise' by default 1979 assert_raises(ValueError, np.busday_offset, '2011-06-04', 0) 1980 1981 # Bigger offset values 1982 assert_equal(np.busday_offset('2006-02-01', 25), 1983 np.datetime64('2006-03-08')) 1984 assert_equal(np.busday_offset('2006-03-08', -25), 1985 np.datetime64('2006-02-01')) 1986 assert_equal(np.busday_offset('2007-02-25', 11, weekmask='SatSun'), 1987 np.datetime64('2007-04-07')) 1988 assert_equal(np.busday_offset('2007-04-07', -11, weekmask='SatSun'), 1989 np.datetime64('2007-02-25')) 1990 1991 # NaT values when roll is not raise 1992 assert_equal(np.busday_offset(np.datetime64('NaT'), 1, roll='nat'), 1993 np.datetime64('NaT')) 1994 assert_equal(np.busday_offset(np.datetime64('NaT'), 1, roll='following'), 1995 np.datetime64('NaT')) 1996 assert_equal(np.busday_offset(np.datetime64('NaT'), 1, roll='preceding'), 1997 np.datetime64('NaT')) 1998 1999 def test_datetime_busdaycalendar(self): 2000 # Check that it removes NaT, duplicates, and weekends 2001 # and sorts the result. 2002 bdd = np.busdaycalendar( 2003 holidays=['NaT', '2011-01-17', '2011-03-06', 'NaT', 2004 '2011-12-26', '2011-05-30', '2011-01-17']) 2005 assert_equal(bdd.holidays, 2006 np.array(['2011-01-17', '2011-05-30', '2011-12-26'], dtype='M8')) 2007 # Default M-F weekmask 2008 assert_equal(bdd.weekmask, np.array([1, 1, 1, 1, 1, 0, 0], dtype='?')) 2009 2010 # Check string weekmask with varying whitespace. 2011 bdd = np.busdaycalendar(weekmask="Sun TueWed Thu\tFri") 2012 assert_equal(bdd.weekmask, np.array([0, 1, 1, 1, 1, 0, 1], dtype='?')) 2013 2014 # Check length 7 0/1 string 2015 bdd = np.busdaycalendar(weekmask="0011001") 2016 assert_equal(bdd.weekmask, np.array([0, 0, 1, 1, 0, 0, 1], dtype='?')) 2017 2018 # Check length 7 string weekmask. 2019 bdd = np.busdaycalendar(weekmask="Mon Tue") 2020 assert_equal(bdd.weekmask, np.array([1, 1, 0, 0, 0, 0, 0], dtype='?')) 2021 2022 # All-zeros weekmask should raise 2023 assert_raises(ValueError, np.busdaycalendar, weekmask=[0, 0, 0, 0, 0, 0, 0]) 2024 # weekday names must be correct case 2025 assert_raises(ValueError, np.busdaycalendar, weekmask="satsun") 2026 # All-zeros weekmask should raise 2027 assert_raises(ValueError, np.busdaycalendar, weekmask="") 2028 # Invalid weekday name codes should raise 2029 assert_raises(ValueError, np.busdaycalendar, weekmask="Mon Tue We") 2030 assert_raises(ValueError, np.busdaycalendar, weekmask="Max") 2031 assert_raises(ValueError, np.busdaycalendar, weekmask="Monday Tue") 2032 2033 def test_datetime_busday_holidays_offset(self): 2034 # With exactly one holiday 2035 assert_equal( 2036 np.busday_offset('2011-11-10', 1, holidays=['2011-11-11']), 2037 np.datetime64('2011-11-14')) 2038 assert_equal( 2039 np.busday_offset('2011-11-04', 5, holidays=['2011-11-11']), 2040 np.datetime64('2011-11-14')) 2041 assert_equal( 2042 np.busday_offset('2011-11-10', 5, holidays=['2011-11-11']), 2043 np.datetime64('2011-11-18')) 2044 assert_equal( 2045 np.busday_offset('2011-11-14', -1, holidays=['2011-11-11']), 2046 np.datetime64('2011-11-10')) 2047 assert_equal( 2048 np.busday_offset('2011-11-18', -5, holidays=['2011-11-11']), 2049 np.datetime64('2011-11-10')) 2050 assert_equal( 2051 np.busday_offset('2011-11-14', -5, holidays=['2011-11-11']), 2052 np.datetime64('2011-11-04')) 2053 # With the holiday appearing twice 2054 assert_equal( 2055 np.busday_offset('2011-11-10', 1, 2056 holidays=['2011-11-11', '2011-11-11']), 2057 np.datetime64('2011-11-14')) 2058 assert_equal( 2059 np.busday_offset('2011-11-14', -1, 2060 holidays=['2011-11-11', '2011-11-11']), 2061 np.datetime64('2011-11-10')) 2062 # With a NaT holiday 2063 assert_equal( 2064 np.busday_offset('2011-11-10', 1, 2065 holidays=['2011-11-11', 'NaT']), 2066 np.datetime64('2011-11-14')) 2067 assert_equal( 2068 np.busday_offset('2011-11-14', -1, 2069 holidays=['NaT', '2011-11-11']), 2070 np.datetime64('2011-11-10')) 2071 # With another holiday after 2072 assert_equal( 2073 np.busday_offset('2011-11-10', 1, 2074 holidays=['2011-11-11', '2011-11-24']), 2075 np.datetime64('2011-11-14')) 2076 assert_equal( 2077 np.busday_offset('2011-11-14', -1, 2078 holidays=['2011-11-11', '2011-11-24']), 2079 np.datetime64('2011-11-10')) 2080 # With another holiday before 2081 assert_equal( 2082 np.busday_offset('2011-11-10', 1, 2083 holidays=['2011-10-10', '2011-11-11']), 2084 np.datetime64('2011-11-14')) 2085 assert_equal( 2086 np.busday_offset('2011-11-14', -1, 2087 holidays=['2011-10-10', '2011-11-11']), 2088 np.datetime64('2011-11-10')) 2089 # With another holiday before and after 2090 assert_equal( 2091 np.busday_offset('2011-11-10', 1, 2092 holidays=['2011-10-10', '2011-11-11', '2011-11-24']), 2093 np.datetime64('2011-11-14')) 2094 assert_equal( 2095 np.busday_offset('2011-11-14', -1, 2096 holidays=['2011-10-10', '2011-11-11', '2011-11-24']), 2097 np.datetime64('2011-11-10')) 2098 2099 # A bigger forward jump across more than one week/holiday 2100 holidays = ['2011-10-10', '2011-11-11', '2011-11-24', 2101 '2011-12-25', '2011-05-30', '2011-02-21', 2102 '2011-12-26', '2012-01-02'] 2103 bdd = np.busdaycalendar(weekmask='1111100', holidays=holidays) 2104 assert_equal( 2105 np.busday_offset('2011-10-03', 4, holidays=holidays), 2106 np.busday_offset('2011-10-03', 4)) 2107 assert_equal( 2108 np.busday_offset('2011-10-03', 5, holidays=holidays), 2109 np.busday_offset('2011-10-03', 5 + 1)) 2110 assert_equal( 2111 np.busday_offset('2011-10-03', 27, holidays=holidays), 2112 np.busday_offset('2011-10-03', 27 + 1)) 2113 assert_equal( 2114 np.busday_offset('2011-10-03', 28, holidays=holidays), 2115 np.busday_offset('2011-10-03', 28 + 2)) 2116 assert_equal( 2117 np.busday_offset('2011-10-03', 35, holidays=holidays), 2118 np.busday_offset('2011-10-03', 35 + 2)) 2119 assert_equal( 2120 np.busday_offset('2011-10-03', 36, holidays=holidays), 2121 np.busday_offset('2011-10-03', 36 + 3)) 2122 assert_equal( 2123 np.busday_offset('2011-10-03', 56, holidays=holidays), 2124 np.busday_offset('2011-10-03', 56 + 3)) 2125 assert_equal( 2126 np.busday_offset('2011-10-03', 57, holidays=holidays), 2127 np.busday_offset('2011-10-03', 57 + 4)) 2128 assert_equal( 2129 np.busday_offset('2011-10-03', 60, holidays=holidays), 2130 np.busday_offset('2011-10-03', 60 + 4)) 2131 assert_equal( 2132 np.busday_offset('2011-10-03', 61, holidays=holidays), 2133 np.busday_offset('2011-10-03', 61 + 5)) 2134 assert_equal( 2135 np.busday_offset('2011-10-03', 61, busdaycal=bdd), 2136 np.busday_offset('2011-10-03', 61 + 5)) 2137 # A bigger backward jump across more than one week/holiday 2138 assert_equal( 2139 np.busday_offset('2012-01-03', -1, holidays=holidays), 2140 np.busday_offset('2012-01-03', -1 - 1)) 2141 assert_equal( 2142 np.busday_offset('2012-01-03', -4, holidays=holidays), 2143 np.busday_offset('2012-01-03', -4 - 1)) 2144 assert_equal( 2145 np.busday_offset('2012-01-03', -5, holidays=holidays), 2146 np.busday_offset('2012-01-03', -5 - 2)) 2147 assert_equal( 2148 np.busday_offset('2012-01-03', -25, holidays=holidays), 2149 np.busday_offset('2012-01-03', -25 - 2)) 2150 assert_equal( 2151 np.busday_offset('2012-01-03', -26, holidays=holidays), 2152 np.busday_offset('2012-01-03', -26 - 3)) 2153 assert_equal( 2154 np.busday_offset('2012-01-03', -33, holidays=holidays), 2155 np.busday_offset('2012-01-03', -33 - 3)) 2156 assert_equal( 2157 np.busday_offset('2012-01-03', -34, holidays=holidays), 2158 np.busday_offset('2012-01-03', -34 - 4)) 2159 assert_equal( 2160 np.busday_offset('2012-01-03', -56, holidays=holidays), 2161 np.busday_offset('2012-01-03', -56 - 4)) 2162 assert_equal( 2163 np.busday_offset('2012-01-03', -57, holidays=holidays), 2164 np.busday_offset('2012-01-03', -57 - 5)) 2165 assert_equal( 2166 np.busday_offset('2012-01-03', -57, busdaycal=bdd), 2167 np.busday_offset('2012-01-03', -57 - 5)) 2168 2169 # Can't supply both a weekmask/holidays and busdaycal 2170 assert_raises(ValueError, np.busday_offset, '2012-01-03', -15, 2171 weekmask='1111100', busdaycal=bdd) 2172 assert_raises(ValueError, np.busday_offset, '2012-01-03', -15, 2173 holidays=holidays, busdaycal=bdd) 2174 2175 # Roll with the holidays 2176 assert_equal( 2177 np.busday_offset('2011-12-25', 0, 2178 roll='forward', holidays=holidays), 2179 np.datetime64('2011-12-27')) 2180 assert_equal( 2181 np.busday_offset('2011-12-26', 0, 2182 roll='forward', holidays=holidays), 2183 np.datetime64('2011-12-27')) 2184 assert_equal( 2185 np.busday_offset('2011-12-26', 0, 2186 roll='backward', holidays=holidays), 2187 np.datetime64('2011-12-23')) 2188 assert_equal( 2189 np.busday_offset('2012-02-27', 0, 2190 roll='modifiedfollowing', 2191 holidays=['2012-02-27', '2012-02-26', '2012-02-28', 2192 '2012-03-01', '2012-02-29']), 2193 np.datetime64('2012-02-24')) 2194 assert_equal( 2195 np.busday_offset('2012-03-06', 0, 2196 roll='modifiedpreceding', 2197 holidays=['2012-03-02', '2012-03-03', '2012-03-01', 2198 '2012-03-05', '2012-03-07', '2012-03-06']), 2199 np.datetime64('2012-03-08')) 2200 2201 def test_datetime_busday_holidays_count(self): 2202 holidays = ['2011-01-01', '2011-10-10', '2011-11-11', '2011-11-24', 2203 '2011-12-25', '2011-05-30', '2011-02-21', '2011-01-17', 2204 '2011-12-26', '2012-01-02', '2011-02-21', '2011-05-30', 2205 '2011-07-01', '2011-07-04', '2011-09-05', '2011-10-10'] 2206 bdd = np.busdaycalendar(weekmask='1111100', holidays=holidays) 2207 2208 # Validate against busday_offset broadcast against 2209 # a range of offsets 2210 dates = np.busday_offset('2011-01-01', np.arange(366), 2211 roll='forward', busdaycal=bdd) 2212 assert_equal(np.busday_count('2011-01-01', dates, busdaycal=bdd), 2213 np.arange(366)) 2214 # Returns negative value when reversed 2215 assert_equal(np.busday_count(dates, '2011-01-01', busdaycal=bdd), 2216 -np.arange(366)) 2217 2218 dates = np.busday_offset('2011-12-31', -np.arange(366), 2219 roll='forward', busdaycal=bdd) 2220 assert_equal(np.busday_count(dates, '2011-12-31', busdaycal=bdd), 2221 np.arange(366)) 2222 # Returns negative value when reversed 2223 assert_equal(np.busday_count('2011-12-31', dates, busdaycal=bdd), 2224 -np.arange(366)) 2225 2226 # Can't supply both a weekmask/holidays and busdaycal 2227 assert_raises(ValueError, np.busday_offset, '2012-01-03', '2012-02-03', 2228 weekmask='1111100', busdaycal=bdd) 2229 assert_raises(ValueError, np.busday_offset, '2012-01-03', '2012-02-03', 2230 holidays=holidays, busdaycal=bdd) 2231 2232 # Number of Mondays in March 2011 2233 assert_equal(np.busday_count('2011-03', '2011-04', weekmask='Mon'), 4) 2234 # Returns negative value when reversed 2235 assert_equal(np.busday_count('2011-04', '2011-03', weekmask='Mon'), -4) 2236 2237 def test_datetime_is_busday(self): 2238 holidays = ['2011-01-01', '2011-10-10', '2011-11-11', '2011-11-24', 2239 '2011-12-25', '2011-05-30', '2011-02-21', '2011-01-17', 2240 '2011-12-26', '2012-01-02', '2011-02-21', '2011-05-30', 2241 '2011-07-01', '2011-07-04', '2011-09-05', '2011-10-10', 2242 'NaT'] 2243 bdd = np.busdaycalendar(weekmask='1111100', holidays=holidays) 2244 2245 # Weekend/weekday tests 2246 assert_equal(np.is_busday('2011-01-01'), False) 2247 assert_equal(np.is_busday('2011-01-02'), False) 2248 assert_equal(np.is_busday('2011-01-03'), True) 2249 2250 # All the holidays are not business days 2251 assert_equal(np.is_busday(holidays, busdaycal=bdd), 2252 np.zeros(len(holidays), dtype='?')) 2253 2254 def test_datetime_y2038(self): 2255 # Test parsing on either side of the Y2038 boundary 2256 a = np.datetime64('2038-01-19T03:14:07') 2257 assert_equal(a.view(np.int64), 2**31 - 1) 2258 a = np.datetime64('2038-01-19T03:14:08') 2259 assert_equal(a.view(np.int64), 2**31) 2260 2261 # Test parsing on either side of the Y2038 boundary with 2262 # a manually specified timezone offset 2263 with assert_warns(DeprecationWarning): 2264 a = np.datetime64('2038-01-19T04:14:07+0100') 2265 assert_equal(a.view(np.int64), 2**31 - 1) 2266 with assert_warns(DeprecationWarning): 2267 a = np.datetime64('2038-01-19T04:14:08+0100') 2268 assert_equal(a.view(np.int64), 2**31) 2269 2270 # Test parsing a date after Y2038 2271 a = np.datetime64('2038-01-20T13:21:14') 2272 assert_equal(str(a), '2038-01-20T13:21:14') 2273 2274 def test_isnat(self): 2275 assert_(np.isnat(np.datetime64('NaT', 'ms'))) 2276 assert_(np.isnat(np.datetime64('NaT', 'ns'))) 2277 assert_(not np.isnat(np.datetime64('2038-01-19T03:14:07'))) 2278 2279 assert_(np.isnat(np.timedelta64('NaT', "ms"))) 2280 assert_(not np.isnat(np.timedelta64(34, "ms"))) 2281 2282 res = np.array([False, False, True]) 2283 for unit in ['Y', 'M', 'W', 'D', 2284 'h', 'm', 's', 'ms', 'us', 2285 'ns', 'ps', 'fs', 'as']: 2286 arr = np.array([123, -321, "NaT"], dtype='<datetime64[%s]' % unit) 2287 assert_equal(np.isnat(arr), res) 2288 arr = np.array([123, -321, "NaT"], dtype='>datetime64[%s]' % unit) 2289 assert_equal(np.isnat(arr), res) 2290 arr = np.array([123, -321, "NaT"], dtype='<timedelta64[%s]' % unit) 2291 assert_equal(np.isnat(arr), res) 2292 arr = np.array([123, -321, "NaT"], dtype='>timedelta64[%s]' % unit) 2293 assert_equal(np.isnat(arr), res) 2294 2295 def test_isnat_error(self): 2296 # Test that only datetime dtype arrays are accepted 2297 for t in np.typecodes["All"]: 2298 if t in np.typecodes["Datetime"]: 2299 continue 2300 assert_raises(TypeError, np.isnat, np.zeros(10, t)) 2301 2302 def test_isfinite_scalar(self): 2303 assert_(not np.isfinite(np.datetime64('NaT', 'ms'))) 2304 assert_(not np.isfinite(np.datetime64('NaT', 'ns'))) 2305 assert_(np.isfinite(np.datetime64('2038-01-19T03:14:07'))) 2306 2307 assert_(not np.isfinite(np.timedelta64('NaT', "ms"))) 2308 assert_(np.isfinite(np.timedelta64(34, "ms"))) 2309 2310 @pytest.mark.parametrize('unit', ['Y', 'M', 'W', 'D', 'h', 'm', 's', 'ms', 2311 'us', 'ns', 'ps', 'fs', 'as']) 2312 @pytest.mark.parametrize('dstr', ['<datetime64[%s]', '>datetime64[%s]', 2313 '<timedelta64[%s]', '>timedelta64[%s]']) 2314 def test_isfinite_isinf_isnan_units(self, unit, dstr): 2315 '''check isfinite, isinf, isnan for all units of <M, >M, <m, >m dtypes 2316 ''' 2317 arr_val = [123, -321, "NaT"] 2318 arr = np.array(arr_val, dtype= dstr % unit) 2319 pos = np.array([True, True, False]) 2320 neg = np.array([False, False, True]) 2321 false = np.array([False, False, False]) 2322 assert_equal(np.isfinite(arr), pos) 2323 assert_equal(np.isinf(arr), false) 2324 assert_equal(np.isnan(arr), neg) 2325 2326 def test_assert_equal(self): 2327 assert_raises(AssertionError, assert_equal, 2328 np.datetime64('nat'), np.timedelta64('nat')) 2329 2330 def test_corecursive_input(self): 2331 # construct a co-recursive list 2332 a, b = [], [] 2333 a.append(b) 2334 b.append(a) 2335 obj_arr = np.array([None]) 2336 obj_arr[0] = a 2337 2338 # At some point this caused a stack overflow (gh-11154). Now raises 2339 # ValueError since the nested list cannot be converted to a datetime. 2340 assert_raises(ValueError, obj_arr.astype, 'M8') 2341 assert_raises(ValueError, obj_arr.astype, 'm8') 2342 2343 @pytest.mark.parametrize("shape", [(), (1,)]) 2344 def test_discovery_from_object_array(self, shape): 2345 arr = np.array("2020-10-10", dtype=object).reshape(shape) 2346 res = np.array("2020-10-10", dtype="M8").reshape(shape) 2347 assert res.dtype == np.dtype("M8[D]") 2348 assert_equal(arr.astype("M8"), res) 2349 arr[...] = np.bytes_("2020-10-10") # try a numpy string type 2350 assert_equal(arr.astype("M8"), res) 2351 arr = arr.astype("S") 2352 assert_equal(arr.astype("S").astype("M8"), res) 2353 2354 @pytest.mark.parametrize("time_unit", [ 2355 "Y", "M", "W", "D", "h", "m", "s", "ms", "us", "ns", "ps", "fs", "as", 2356 # compound units 2357 "10D", "2M", 2358 ]) 2359 def test_limit_symmetry(self, time_unit): 2360 """ 2361 Dates should have symmetric limits around the unix epoch at +/-np.int64 2362 """ 2363 epoch = np.datetime64(0, time_unit) 2364 latest = np.datetime64(np.iinfo(np.int64).max, time_unit) 2365 earliest = np.datetime64(-np.iinfo(np.int64).max, time_unit) 2366 2367 # above should not have overflowed 2368 assert earliest < epoch < latest 2369 2370 @pytest.mark.parametrize("time_unit", [ 2371 "Y", "M", 2372 pytest.param("W", marks=pytest.mark.xfail(reason="gh-13197")), 2373 "D", "h", "m", 2374 "s", "ms", "us", "ns", "ps", "fs", "as", 2375 pytest.param("10D", marks=pytest.mark.xfail(reason="similar to gh-13197")), 2376 ]) 2377 @pytest.mark.parametrize("sign", [-1, 1]) 2378 def test_limit_str_roundtrip(self, time_unit, sign): 2379 """ 2380 Limits should roundtrip when converted to strings. 2381 2382 This tests the conversion to and from npy_datetimestruct. 2383 """ 2384 # TODO: add absolute (gold standard) time span limit strings 2385 limit = np.datetime64(np.iinfo(np.int64).max * sign, time_unit) 2386 2387 # Convert to string and back. Explicit unit needed since the day and 2388 # week reprs are not distinguishable. 2389 limit_via_str = np.datetime64(str(limit), time_unit) 2390 assert limit_via_str == limit 2391 2392 2393class TestDateTimeData: 2394 2395 def test_basic(self): 2396 a = np.array(['1980-03-23'], dtype=np.datetime64) 2397 assert_equal(np.datetime_data(a.dtype), ('D', 1)) 2398 2399 def test_bytes(self): 2400 # byte units are converted to unicode 2401 dt = np.datetime64('2000', (b'ms', 5)) 2402 assert np.datetime_data(dt.dtype) == ('ms', 5) 2403 2404 dt = np.datetime64('2000', b'5ms') 2405 assert np.datetime_data(dt.dtype) == ('ms', 5) 2406 2407 def test_non_ascii(self): 2408 # μs is normalized to μ 2409 dt = np.datetime64('2000', ('μs', 5)) 2410 assert np.datetime_data(dt.dtype) == ('us', 5) 2411 2412 dt = np.datetime64('2000', '5μs') 2413 assert np.datetime_data(dt.dtype) == ('us', 5) 2414