test_datetime.py 113 KB

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