test_period.py 51 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495
  1. from datetime import date, datetime, timedelta
  2. import numpy as np
  3. import pytest
  4. import pytz
  5. from pandas._libs.tslibs import iNaT, period as libperiod
  6. from pandas._libs.tslibs.ccalendar import DAYS, MONTHS
  7. from pandas._libs.tslibs.frequencies import INVALID_FREQ_ERR_MSG
  8. from pandas._libs.tslibs.parsing import DateParseError
  9. from pandas._libs.tslibs.timezones import dateutil_gettz, maybe_get_tz
  10. from pandas.compat import iteritems, text_type
  11. from pandas.compat.numpy import np_datetime64_compat
  12. import pandas as pd
  13. from pandas import NaT, Period, Timedelta, Timestamp, offsets
  14. import pandas.core.indexes.period as period
  15. import pandas.util.testing as tm
  16. class TestPeriodConstruction(object):
  17. def test_construction(self):
  18. i1 = Period('1/1/2005', freq='M')
  19. i2 = Period('Jan 2005')
  20. assert i1 == i2
  21. i1 = Period('2005', freq='A')
  22. i2 = Period('2005')
  23. i3 = Period('2005', freq='a')
  24. assert i1 == i2
  25. assert i1 == i3
  26. i4 = Period('2005', freq='M')
  27. i5 = Period('2005', freq='m')
  28. pytest.raises(ValueError, i1.__ne__, i4)
  29. assert i4 == i5
  30. i1 = Period.now('Q')
  31. i2 = Period(datetime.now(), freq='Q')
  32. i3 = Period.now('q')
  33. assert i1 == i2
  34. assert i1 == i3
  35. i1 = Period('1982', freq='min')
  36. i2 = Period('1982', freq='MIN')
  37. assert i1 == i2
  38. i2 = Period('1982', freq=('Min', 1))
  39. assert i1 == i2
  40. i1 = Period(year=2005, month=3, day=1, freq='D')
  41. i2 = Period('3/1/2005', freq='D')
  42. assert i1 == i2
  43. i3 = Period(year=2005, month=3, day=1, freq='d')
  44. assert i1 == i3
  45. i1 = Period('2007-01-01 09:00:00.001')
  46. expected = Period(datetime(2007, 1, 1, 9, 0, 0, 1000), freq='L')
  47. assert i1 == expected
  48. expected = Period(np_datetime64_compat(
  49. '2007-01-01 09:00:00.001Z'), freq='L')
  50. assert i1 == expected
  51. i1 = Period('2007-01-01 09:00:00.00101')
  52. expected = Period(datetime(2007, 1, 1, 9, 0, 0, 1010), freq='U')
  53. assert i1 == expected
  54. expected = Period(np_datetime64_compat('2007-01-01 09:00:00.00101Z'),
  55. freq='U')
  56. assert i1 == expected
  57. pytest.raises(ValueError, Period, ordinal=200701)
  58. pytest.raises(ValueError, Period, '2007-1-1', freq='X')
  59. def test_construction_bday(self):
  60. # Biz day construction, roll forward if non-weekday
  61. i1 = Period('3/10/12', freq='B')
  62. i2 = Period('3/10/12', freq='D')
  63. assert i1 == i2.asfreq('B')
  64. i2 = Period('3/11/12', freq='D')
  65. assert i1 == i2.asfreq('B')
  66. i2 = Period('3/12/12', freq='D')
  67. assert i1 == i2.asfreq('B')
  68. i3 = Period('3/10/12', freq='b')
  69. assert i1 == i3
  70. i1 = Period(year=2012, month=3, day=10, freq='B')
  71. i2 = Period('3/12/12', freq='B')
  72. assert i1 == i2
  73. def test_construction_quarter(self):
  74. i1 = Period(year=2005, quarter=1, freq='Q')
  75. i2 = Period('1/1/2005', freq='Q')
  76. assert i1 == i2
  77. i1 = Period(year=2005, quarter=3, freq='Q')
  78. i2 = Period('9/1/2005', freq='Q')
  79. assert i1 == i2
  80. i1 = Period('2005Q1')
  81. i2 = Period(year=2005, quarter=1, freq='Q')
  82. i3 = Period('2005q1')
  83. assert i1 == i2
  84. assert i1 == i3
  85. i1 = Period('05Q1')
  86. assert i1 == i2
  87. lower = Period('05q1')
  88. assert i1 == lower
  89. i1 = Period('1Q2005')
  90. assert i1 == i2
  91. lower = Period('1q2005')
  92. assert i1 == lower
  93. i1 = Period('1Q05')
  94. assert i1 == i2
  95. lower = Period('1q05')
  96. assert i1 == lower
  97. i1 = Period('4Q1984')
  98. assert i1.year == 1984
  99. lower = Period('4q1984')
  100. assert i1 == lower
  101. def test_construction_month(self):
  102. expected = Period('2007-01', freq='M')
  103. i1 = Period('200701', freq='M')
  104. assert i1 == expected
  105. i1 = Period('200701', freq='M')
  106. assert i1 == expected
  107. i1 = Period(200701, freq='M')
  108. assert i1 == expected
  109. i1 = Period(ordinal=200701, freq='M')
  110. assert i1.year == 18695
  111. i1 = Period(datetime(2007, 1, 1), freq='M')
  112. i2 = Period('200701', freq='M')
  113. assert i1 == i2
  114. i1 = Period(date(2007, 1, 1), freq='M')
  115. i2 = Period(datetime(2007, 1, 1), freq='M')
  116. i3 = Period(np.datetime64('2007-01-01'), freq='M')
  117. i4 = Period(np_datetime64_compat('2007-01-01 00:00:00Z'), freq='M')
  118. i5 = Period(np_datetime64_compat('2007-01-01 00:00:00.000Z'), freq='M')
  119. assert i1 == i2
  120. assert i1 == i3
  121. assert i1 == i4
  122. assert i1 == i5
  123. def test_period_constructor_offsets(self):
  124. assert (Period('1/1/2005', freq=offsets.MonthEnd()) ==
  125. Period('1/1/2005', freq='M'))
  126. assert (Period('2005', freq=offsets.YearEnd()) ==
  127. Period('2005', freq='A'))
  128. assert (Period('2005', freq=offsets.MonthEnd()) ==
  129. Period('2005', freq='M'))
  130. assert (Period('3/10/12', freq=offsets.BusinessDay()) ==
  131. Period('3/10/12', freq='B'))
  132. assert (Period('3/10/12', freq=offsets.Day()) ==
  133. Period('3/10/12', freq='D'))
  134. assert (Period(year=2005, quarter=1,
  135. freq=offsets.QuarterEnd(startingMonth=12)) ==
  136. Period(year=2005, quarter=1, freq='Q'))
  137. assert (Period(year=2005, quarter=2,
  138. freq=offsets.QuarterEnd(startingMonth=12)) ==
  139. Period(year=2005, quarter=2, freq='Q'))
  140. assert (Period(year=2005, month=3, day=1, freq=offsets.Day()) ==
  141. Period(year=2005, month=3, day=1, freq='D'))
  142. assert (Period(year=2012, month=3, day=10, freq=offsets.BDay()) ==
  143. Period(year=2012, month=3, day=10, freq='B'))
  144. expected = Period('2005-03-01', freq='3D')
  145. assert (Period(year=2005, month=3, day=1,
  146. freq=offsets.Day(3)) == expected)
  147. assert Period(year=2005, month=3, day=1, freq='3D') == expected
  148. assert (Period(year=2012, month=3, day=10,
  149. freq=offsets.BDay(3)) ==
  150. Period(year=2012, month=3, day=10, freq='3B'))
  151. assert (Period(200701, freq=offsets.MonthEnd()) ==
  152. Period(200701, freq='M'))
  153. i1 = Period(ordinal=200701, freq=offsets.MonthEnd())
  154. i2 = Period(ordinal=200701, freq='M')
  155. assert i1 == i2
  156. assert i1.year == 18695
  157. assert i2.year == 18695
  158. i1 = Period(datetime(2007, 1, 1), freq='M')
  159. i2 = Period('200701', freq='M')
  160. assert i1 == i2
  161. i1 = Period(date(2007, 1, 1), freq='M')
  162. i2 = Period(datetime(2007, 1, 1), freq='M')
  163. i3 = Period(np.datetime64('2007-01-01'), freq='M')
  164. i4 = Period(np_datetime64_compat('2007-01-01 00:00:00Z'), freq='M')
  165. i5 = Period(np_datetime64_compat('2007-01-01 00:00:00.000Z'), freq='M')
  166. assert i1 == i2
  167. assert i1 == i3
  168. assert i1 == i4
  169. assert i1 == i5
  170. i1 = Period('2007-01-01 09:00:00.001')
  171. expected = Period(datetime(2007, 1, 1, 9, 0, 0, 1000), freq='L')
  172. assert i1 == expected
  173. expected = Period(np_datetime64_compat(
  174. '2007-01-01 09:00:00.001Z'), freq='L')
  175. assert i1 == expected
  176. i1 = Period('2007-01-01 09:00:00.00101')
  177. expected = Period(datetime(2007, 1, 1, 9, 0, 0, 1010), freq='U')
  178. assert i1 == expected
  179. expected = Period(np_datetime64_compat('2007-01-01 09:00:00.00101Z'),
  180. freq='U')
  181. assert i1 == expected
  182. pytest.raises(ValueError, Period, ordinal=200701)
  183. pytest.raises(ValueError, Period, '2007-1-1', freq='X')
  184. def test_invalid_arguments(self):
  185. with pytest.raises(ValueError):
  186. Period(datetime.now())
  187. with pytest.raises(ValueError):
  188. Period(datetime.now().date())
  189. with pytest.raises(ValueError):
  190. Period(1.6, freq='D')
  191. with pytest.raises(ValueError):
  192. Period(ordinal=1.6, freq='D')
  193. with pytest.raises(ValueError):
  194. Period(ordinal=2, value=1, freq='D')
  195. with pytest.raises(ValueError):
  196. Period(month=1)
  197. with pytest.raises(ValueError):
  198. Period('-2000', 'A')
  199. with pytest.raises(DateParseError):
  200. Period('0', 'A')
  201. with pytest.raises(DateParseError):
  202. Period('1/1/-2000', 'A')
  203. def test_constructor_corner(self):
  204. expected = Period('2007-01', freq='2M')
  205. assert Period(year=2007, month=1, freq='2M') == expected
  206. assert Period(None) is NaT
  207. p = Period('2007-01-01', freq='D')
  208. result = Period(p, freq='A')
  209. exp = Period('2007', freq='A')
  210. assert result == exp
  211. def test_constructor_infer_freq(self):
  212. p = Period('2007-01-01')
  213. assert p.freq == 'D'
  214. p = Period('2007-01-01 07')
  215. assert p.freq == 'H'
  216. p = Period('2007-01-01 07:10')
  217. assert p.freq == 'T'
  218. p = Period('2007-01-01 07:10:15')
  219. assert p.freq == 'S'
  220. p = Period('2007-01-01 07:10:15.123')
  221. assert p.freq == 'L'
  222. p = Period('2007-01-01 07:10:15.123000')
  223. assert p.freq == 'L'
  224. p = Period('2007-01-01 07:10:15.123400')
  225. assert p.freq == 'U'
  226. def test_multiples(self):
  227. result1 = Period('1989', freq='2A')
  228. result2 = Period('1989', freq='A')
  229. assert result1.ordinal == result2.ordinal
  230. assert result1.freqstr == '2A-DEC'
  231. assert result2.freqstr == 'A-DEC'
  232. assert result1.freq == offsets.YearEnd(2)
  233. assert result2.freq == offsets.YearEnd()
  234. assert (result1 + 1).ordinal == result1.ordinal + 2
  235. assert (1 + result1).ordinal == result1.ordinal + 2
  236. assert (result1 - 1).ordinal == result2.ordinal - 2
  237. assert (-1 + result1).ordinal == result2.ordinal - 2
  238. @pytest.mark.parametrize('month', MONTHS)
  239. def test_period_cons_quarterly(self, month):
  240. # bugs in scikits.timeseries
  241. freq = 'Q-%s' % month
  242. exp = Period('1989Q3', freq=freq)
  243. assert '1989Q3' in str(exp)
  244. stamp = exp.to_timestamp('D', how='end')
  245. p = Period(stamp, freq=freq)
  246. assert p == exp
  247. stamp = exp.to_timestamp('3D', how='end')
  248. p = Period(stamp, freq=freq)
  249. assert p == exp
  250. @pytest.mark.parametrize('month', MONTHS)
  251. def test_period_cons_annual(self, month):
  252. # bugs in scikits.timeseries
  253. freq = 'A-%s' % month
  254. exp = Period('1989', freq=freq)
  255. stamp = exp.to_timestamp('D', how='end') + timedelta(days=30)
  256. p = Period(stamp, freq=freq)
  257. assert p == exp + 1
  258. assert isinstance(p, Period)
  259. @pytest.mark.parametrize('day', DAYS)
  260. @pytest.mark.parametrize('num', range(10, 17))
  261. def test_period_cons_weekly(self, num, day):
  262. daystr = '2011-02-%d' % num
  263. freq = 'W-%s' % day
  264. result = Period(daystr, freq=freq)
  265. expected = Period(daystr, freq='D').asfreq(freq)
  266. assert result == expected
  267. assert isinstance(result, Period)
  268. def test_period_from_ordinal(self):
  269. p = Period('2011-01', freq='M')
  270. res = Period._from_ordinal(p.ordinal, freq='M')
  271. assert p == res
  272. assert isinstance(res, Period)
  273. def test_period_cons_nat(self):
  274. p = Period('NaT', freq='M')
  275. assert p is NaT
  276. p = Period('nat', freq='W-SUN')
  277. assert p is NaT
  278. p = Period(iNaT, freq='D')
  279. assert p is NaT
  280. p = Period(iNaT, freq='3D')
  281. assert p is NaT
  282. p = Period(iNaT, freq='1D1H')
  283. assert p is NaT
  284. p = Period('NaT')
  285. assert p is NaT
  286. p = Period(iNaT)
  287. assert p is NaT
  288. def test_period_cons_mult(self):
  289. p1 = Period('2011-01', freq='3M')
  290. p2 = Period('2011-01', freq='M')
  291. assert p1.ordinal == p2.ordinal
  292. assert p1.freq == offsets.MonthEnd(3)
  293. assert p1.freqstr == '3M'
  294. assert p2.freq == offsets.MonthEnd()
  295. assert p2.freqstr == 'M'
  296. result = p1 + 1
  297. assert result.ordinal == (p2 + 3).ordinal
  298. assert result.freq == p1.freq
  299. assert result.freqstr == '3M'
  300. result = p1 - 1
  301. assert result.ordinal == (p2 - 3).ordinal
  302. assert result.freq == p1.freq
  303. assert result.freqstr == '3M'
  304. msg = ('Frequency must be positive, because it'
  305. ' represents span: -3M')
  306. with pytest.raises(ValueError, match=msg):
  307. Period('2011-01', freq='-3M')
  308. msg = ('Frequency must be positive, because it' ' represents span: 0M')
  309. with pytest.raises(ValueError, match=msg):
  310. Period('2011-01', freq='0M')
  311. def test_period_cons_combined(self):
  312. p = [(Period('2011-01', freq='1D1H'),
  313. Period('2011-01', freq='1H1D'),
  314. Period('2011-01', freq='H')),
  315. (Period(ordinal=1, freq='1D1H'),
  316. Period(ordinal=1, freq='1H1D'),
  317. Period(ordinal=1, freq='H'))]
  318. for p1, p2, p3 in p:
  319. assert p1.ordinal == p3.ordinal
  320. assert p2.ordinal == p3.ordinal
  321. assert p1.freq == offsets.Hour(25)
  322. assert p1.freqstr == '25H'
  323. assert p2.freq == offsets.Hour(25)
  324. assert p2.freqstr == '25H'
  325. assert p3.freq == offsets.Hour()
  326. assert p3.freqstr == 'H'
  327. result = p1 + 1
  328. assert result.ordinal == (p3 + 25).ordinal
  329. assert result.freq == p1.freq
  330. assert result.freqstr == '25H'
  331. result = p2 + 1
  332. assert result.ordinal == (p3 + 25).ordinal
  333. assert result.freq == p2.freq
  334. assert result.freqstr == '25H'
  335. result = p1 - 1
  336. assert result.ordinal == (p3 - 25).ordinal
  337. assert result.freq == p1.freq
  338. assert result.freqstr == '25H'
  339. result = p2 - 1
  340. assert result.ordinal == (p3 - 25).ordinal
  341. assert result.freq == p2.freq
  342. assert result.freqstr == '25H'
  343. msg = ('Frequency must be positive, because it'
  344. ' represents span: -25H')
  345. with pytest.raises(ValueError, match=msg):
  346. Period('2011-01', freq='-1D1H')
  347. with pytest.raises(ValueError, match=msg):
  348. Period('2011-01', freq='-1H1D')
  349. with pytest.raises(ValueError, match=msg):
  350. Period(ordinal=1, freq='-1D1H')
  351. with pytest.raises(ValueError, match=msg):
  352. Period(ordinal=1, freq='-1H1D')
  353. msg = ('Frequency must be positive, because it'
  354. ' represents span: 0D')
  355. with pytest.raises(ValueError, match=msg):
  356. Period('2011-01', freq='0D0H')
  357. with pytest.raises(ValueError, match=msg):
  358. Period(ordinal=1, freq='0D0H')
  359. # You can only combine together day and intraday offsets
  360. msg = ('Invalid frequency: 1W1D')
  361. with pytest.raises(ValueError, match=msg):
  362. Period('2011-01', freq='1W1D')
  363. msg = ('Invalid frequency: 1D1W')
  364. with pytest.raises(ValueError, match=msg):
  365. Period('2011-01', freq='1D1W')
  366. class TestPeriodMethods(object):
  367. def test_round_trip(self):
  368. p = Period('2000Q1')
  369. new_p = tm.round_trip_pickle(p)
  370. assert new_p == p
  371. def test_hash(self):
  372. assert (hash(Period('2011-01', freq='M')) ==
  373. hash(Period('2011-01', freq='M')))
  374. assert (hash(Period('2011-01-01', freq='D')) !=
  375. hash(Period('2011-01', freq='M')))
  376. assert (hash(Period('2011-01', freq='3M')) !=
  377. hash(Period('2011-01', freq='2M')))
  378. assert (hash(Period('2011-01', freq='M')) !=
  379. hash(Period('2011-02', freq='M')))
  380. # --------------------------------------------------------------
  381. # to_timestamp
  382. @pytest.mark.parametrize('tzstr', ['Europe/Brussels',
  383. 'Asia/Tokyo', 'US/Pacific'])
  384. def test_to_timestamp_tz_arg(self, tzstr):
  385. p = Period('1/1/2005', freq='M').to_timestamp(tz=tzstr)
  386. exp = Timestamp('1/1/2005', tz='UTC').tz_convert(tzstr)
  387. exp_zone = pytz.timezone(tzstr).normalize(p)
  388. assert p == exp
  389. assert p.tz == exp_zone.tzinfo
  390. assert p.tz == exp.tz
  391. p = Period('1/1/2005', freq='3H').to_timestamp(tz=tzstr)
  392. exp = Timestamp('1/1/2005', tz='UTC').tz_convert(tzstr)
  393. exp_zone = pytz.timezone(tzstr).normalize(p)
  394. assert p == exp
  395. assert p.tz == exp_zone.tzinfo
  396. assert p.tz == exp.tz
  397. p = Period('1/1/2005', freq='A').to_timestamp(freq='A', tz=tzstr)
  398. exp = Timestamp('31/12/2005', tz='UTC').tz_convert(tzstr)
  399. exp_zone = pytz.timezone(tzstr).normalize(p)
  400. assert p == exp
  401. assert p.tz == exp_zone.tzinfo
  402. assert p.tz == exp.tz
  403. p = Period('1/1/2005', freq='A').to_timestamp(freq='3H', tz=tzstr)
  404. exp = Timestamp('1/1/2005', tz='UTC').tz_convert(tzstr)
  405. exp_zone = pytz.timezone(tzstr).normalize(p)
  406. assert p == exp
  407. assert p.tz == exp_zone.tzinfo
  408. assert p.tz == exp.tz
  409. @pytest.mark.parametrize('tzstr', ['dateutil/Europe/Brussels',
  410. 'dateutil/Asia/Tokyo',
  411. 'dateutil/US/Pacific'])
  412. def test_to_timestamp_tz_arg_dateutil(self, tzstr):
  413. tz = maybe_get_tz(tzstr)
  414. p = Period('1/1/2005', freq='M').to_timestamp(tz=tz)
  415. exp = Timestamp('1/1/2005', tz='UTC').tz_convert(tzstr)
  416. assert p == exp
  417. assert p.tz == dateutil_gettz(tzstr.split('/', 1)[1])
  418. assert p.tz == exp.tz
  419. p = Period('1/1/2005', freq='M').to_timestamp(freq='3H', tz=tz)
  420. exp = Timestamp('1/1/2005', tz='UTC').tz_convert(tzstr)
  421. assert p == exp
  422. assert p.tz == dateutil_gettz(tzstr.split('/', 1)[1])
  423. assert p.tz == exp.tz
  424. def test_to_timestamp_tz_arg_dateutil_from_string(self):
  425. p = Period('1/1/2005',
  426. freq='M').to_timestamp(tz='dateutil/Europe/Brussels')
  427. assert p.tz == dateutil_gettz('Europe/Brussels')
  428. def test_to_timestamp_mult(self):
  429. p = Period('2011-01', freq='M')
  430. assert p.to_timestamp(how='S') == Timestamp('2011-01-01')
  431. expected = Timestamp('2011-02-01') - Timedelta(1, 'ns')
  432. assert p.to_timestamp(how='E') == expected
  433. p = Period('2011-01', freq='3M')
  434. assert p.to_timestamp(how='S') == Timestamp('2011-01-01')
  435. expected = Timestamp('2011-04-01') - Timedelta(1, 'ns')
  436. assert p.to_timestamp(how='E') == expected
  437. def test_to_timestamp(self):
  438. p = Period('1982', freq='A')
  439. start_ts = p.to_timestamp(how='S')
  440. aliases = ['s', 'StarT', 'BEGIn']
  441. for a in aliases:
  442. assert start_ts == p.to_timestamp('D', how=a)
  443. # freq with mult should not affect to the result
  444. assert start_ts == p.to_timestamp('3D', how=a)
  445. end_ts = p.to_timestamp(how='E')
  446. aliases = ['e', 'end', 'FINIsH']
  447. for a in aliases:
  448. assert end_ts == p.to_timestamp('D', how=a)
  449. assert end_ts == p.to_timestamp('3D', how=a)
  450. from_lst = ['A', 'Q', 'M', 'W', 'B', 'D', 'H', 'Min', 'S']
  451. def _ex(p):
  452. return Timestamp((p + p.freq).start_time.value - 1)
  453. for i, fcode in enumerate(from_lst):
  454. p = Period('1982', freq=fcode)
  455. result = p.to_timestamp().to_period(fcode)
  456. assert result == p
  457. assert p.start_time == p.to_timestamp(how='S')
  458. assert p.end_time == _ex(p)
  459. # Frequency other than daily
  460. p = Period('1985', freq='A')
  461. result = p.to_timestamp('H', how='end')
  462. expected = Timestamp(1986, 1, 1) - Timedelta(1, 'ns')
  463. assert result == expected
  464. result = p.to_timestamp('3H', how='end')
  465. assert result == expected
  466. result = p.to_timestamp('T', how='end')
  467. expected = Timestamp(1986, 1, 1) - Timedelta(1, 'ns')
  468. assert result == expected
  469. result = p.to_timestamp('2T', how='end')
  470. assert result == expected
  471. result = p.to_timestamp(how='end')
  472. expected = Timestamp(1986, 1, 1) - Timedelta(1, 'ns')
  473. assert result == expected
  474. expected = datetime(1985, 1, 1)
  475. result = p.to_timestamp('H', how='start')
  476. assert result == expected
  477. result = p.to_timestamp('T', how='start')
  478. assert result == expected
  479. result = p.to_timestamp('S', how='start')
  480. assert result == expected
  481. result = p.to_timestamp('3H', how='start')
  482. assert result == expected
  483. result = p.to_timestamp('5S', how='start')
  484. assert result == expected
  485. # --------------------------------------------------------------
  486. # Rendering: __repr__, strftime, etc
  487. def test_repr(self):
  488. p = Period('Jan-2000')
  489. assert '2000-01' in repr(p)
  490. p = Period('2000-12-15')
  491. assert '2000-12-15' in repr(p)
  492. def test_repr_nat(self):
  493. p = Period('nat', freq='M')
  494. assert repr(NaT) in repr(p)
  495. def test_millisecond_repr(self):
  496. p = Period('2000-01-01 12:15:02.123')
  497. assert repr(p) == "Period('2000-01-01 12:15:02.123', 'L')"
  498. def test_microsecond_repr(self):
  499. p = Period('2000-01-01 12:15:02.123567')
  500. assert repr(p) == "Period('2000-01-01 12:15:02.123567', 'U')"
  501. def test_strftime(self):
  502. # GH#3363
  503. p = Period('2000-1-1 12:34:12', freq='S')
  504. res = p.strftime('%Y-%m-%d %H:%M:%S')
  505. assert res == '2000-01-01 12:34:12'
  506. assert isinstance(res, text_type)
  507. class TestPeriodProperties(object):
  508. "Test properties such as year, month, weekday, etc...."
  509. @pytest.mark.parametrize('freq', ['A', 'M', 'D', 'H'])
  510. def test_is_leap_year(self, freq):
  511. # GH 13727
  512. p = Period('2000-01-01 00:00:00', freq=freq)
  513. assert p.is_leap_year
  514. assert isinstance(p.is_leap_year, bool)
  515. p = Period('1999-01-01 00:00:00', freq=freq)
  516. assert not p.is_leap_year
  517. p = Period('2004-01-01 00:00:00', freq=freq)
  518. assert p.is_leap_year
  519. p = Period('2100-01-01 00:00:00', freq=freq)
  520. assert not p.is_leap_year
  521. def test_quarterly_negative_ordinals(self):
  522. p = Period(ordinal=-1, freq='Q-DEC')
  523. assert p.year == 1969
  524. assert p.quarter == 4
  525. assert isinstance(p, Period)
  526. p = Period(ordinal=-2, freq='Q-DEC')
  527. assert p.year == 1969
  528. assert p.quarter == 3
  529. assert isinstance(p, Period)
  530. p = Period(ordinal=-2, freq='M')
  531. assert p.year == 1969
  532. assert p.month == 11
  533. assert isinstance(p, Period)
  534. def test_freq_str(self):
  535. i1 = Period('1982', freq='Min')
  536. assert i1.freq == offsets.Minute()
  537. assert i1.freqstr == 'T'
  538. def test_period_deprecated_freq(self):
  539. cases = {"M": ["MTH", "MONTH", "MONTHLY", "Mth", "month", "monthly"],
  540. "B": ["BUS", "BUSINESS", "BUSINESSLY", "WEEKDAY", "bus"],
  541. "D": ["DAY", "DLY", "DAILY", "Day", "Dly", "Daily"],
  542. "H": ["HR", "HOUR", "HRLY", "HOURLY", "hr", "Hour", "HRly"],
  543. "T": ["minute", "MINUTE", "MINUTELY", "minutely"],
  544. "S": ["sec", "SEC", "SECOND", "SECONDLY", "second"],
  545. "L": ["MILLISECOND", "MILLISECONDLY", "millisecond"],
  546. "U": ["MICROSECOND", "MICROSECONDLY", "microsecond"],
  547. "N": ["NANOSECOND", "NANOSECONDLY", "nanosecond"]}
  548. msg = INVALID_FREQ_ERR_MSG
  549. for exp, freqs in iteritems(cases):
  550. for freq in freqs:
  551. with pytest.raises(ValueError, match=msg):
  552. Period('2016-03-01 09:00', freq=freq)
  553. with pytest.raises(ValueError, match=msg):
  554. Period(ordinal=1, freq=freq)
  555. # check supported freq-aliases still works
  556. p1 = Period('2016-03-01 09:00', freq=exp)
  557. p2 = Period(ordinal=1, freq=exp)
  558. assert isinstance(p1, Period)
  559. assert isinstance(p2, Period)
  560. def test_start_time(self):
  561. freq_lst = ['A', 'Q', 'M', 'D', 'H', 'T', 'S']
  562. xp = datetime(2012, 1, 1)
  563. for f in freq_lst:
  564. p = Period('2012', freq=f)
  565. assert p.start_time == xp
  566. assert Period('2012', freq='B').start_time == datetime(2012, 1, 2)
  567. assert Period('2012', freq='W').start_time == datetime(2011, 12, 26)
  568. def test_end_time(self):
  569. p = Period('2012', freq='A')
  570. def _ex(*args):
  571. return Timestamp(Timestamp(datetime(*args)).value - 1)
  572. xp = _ex(2013, 1, 1)
  573. assert xp == p.end_time
  574. p = Period('2012', freq='Q')
  575. xp = _ex(2012, 4, 1)
  576. assert xp == p.end_time
  577. p = Period('2012', freq='M')
  578. xp = _ex(2012, 2, 1)
  579. assert xp == p.end_time
  580. p = Period('2012', freq='D')
  581. xp = _ex(2012, 1, 2)
  582. assert xp == p.end_time
  583. p = Period('2012', freq='H')
  584. xp = _ex(2012, 1, 1, 1)
  585. assert xp == p.end_time
  586. p = Period('2012', freq='B')
  587. xp = _ex(2012, 1, 3)
  588. assert xp == p.end_time
  589. p = Period('2012', freq='W')
  590. xp = _ex(2012, 1, 2)
  591. assert xp == p.end_time
  592. # Test for GH 11738
  593. p = Period('2012', freq='15D')
  594. xp = _ex(2012, 1, 16)
  595. assert xp == p.end_time
  596. p = Period('2012', freq='1D1H')
  597. xp = _ex(2012, 1, 2, 1)
  598. assert xp == p.end_time
  599. p = Period('2012', freq='1H1D')
  600. xp = _ex(2012, 1, 2, 1)
  601. assert xp == p.end_time
  602. def test_anchor_week_end_time(self):
  603. def _ex(*args):
  604. return Timestamp(Timestamp(datetime(*args)).value - 1)
  605. p = Period('2013-1-1', 'W-SAT')
  606. xp = _ex(2013, 1, 6)
  607. assert p.end_time == xp
  608. def test_properties_annually(self):
  609. # Test properties on Periods with annually frequency.
  610. a_date = Period(freq='A', year=2007)
  611. assert a_date.year == 2007
  612. def test_properties_quarterly(self):
  613. # Test properties on Periods with daily frequency.
  614. qedec_date = Period(freq="Q-DEC", year=2007, quarter=1)
  615. qejan_date = Period(freq="Q-JAN", year=2007, quarter=1)
  616. qejun_date = Period(freq="Q-JUN", year=2007, quarter=1)
  617. #
  618. for x in range(3):
  619. for qd in (qedec_date, qejan_date, qejun_date):
  620. assert (qd + x).qyear == 2007
  621. assert (qd + x).quarter == x + 1
  622. def test_properties_monthly(self):
  623. # Test properties on Periods with daily frequency.
  624. m_date = Period(freq='M', year=2007, month=1)
  625. for x in range(11):
  626. m_ival_x = m_date + x
  627. assert m_ival_x.year == 2007
  628. if 1 <= x + 1 <= 3:
  629. assert m_ival_x.quarter == 1
  630. elif 4 <= x + 1 <= 6:
  631. assert m_ival_x.quarter == 2
  632. elif 7 <= x + 1 <= 9:
  633. assert m_ival_x.quarter == 3
  634. elif 10 <= x + 1 <= 12:
  635. assert m_ival_x.quarter == 4
  636. assert m_ival_x.month == x + 1
  637. def test_properties_weekly(self):
  638. # Test properties on Periods with daily frequency.
  639. w_date = Period(freq='W', year=2007, month=1, day=7)
  640. #
  641. assert w_date.year == 2007
  642. assert w_date.quarter == 1
  643. assert w_date.month == 1
  644. assert w_date.week == 1
  645. assert (w_date - 1).week == 52
  646. assert w_date.days_in_month == 31
  647. assert Period(freq='W', year=2012,
  648. month=2, day=1).days_in_month == 29
  649. def test_properties_weekly_legacy(self):
  650. # Test properties on Periods with daily frequency.
  651. w_date = Period(freq='W', year=2007, month=1, day=7)
  652. assert w_date.year == 2007
  653. assert w_date.quarter == 1
  654. assert w_date.month == 1
  655. assert w_date.week == 1
  656. assert (w_date - 1).week == 52
  657. assert w_date.days_in_month == 31
  658. exp = Period(freq='W', year=2012, month=2, day=1)
  659. assert exp.days_in_month == 29
  660. msg = INVALID_FREQ_ERR_MSG
  661. with pytest.raises(ValueError, match=msg):
  662. Period(freq='WK', year=2007, month=1, day=7)
  663. def test_properties_daily(self):
  664. # Test properties on Periods with daily frequency.
  665. b_date = Period(freq='B', year=2007, month=1, day=1)
  666. #
  667. assert b_date.year == 2007
  668. assert b_date.quarter == 1
  669. assert b_date.month == 1
  670. assert b_date.day == 1
  671. assert b_date.weekday == 0
  672. assert b_date.dayofyear == 1
  673. assert b_date.days_in_month == 31
  674. assert Period(freq='B', year=2012,
  675. month=2, day=1).days_in_month == 29
  676. d_date = Period(freq='D', year=2007, month=1, day=1)
  677. assert d_date.year == 2007
  678. assert d_date.quarter == 1
  679. assert d_date.month == 1
  680. assert d_date.day == 1
  681. assert d_date.weekday == 0
  682. assert d_date.dayofyear == 1
  683. assert d_date.days_in_month == 31
  684. assert Period(freq='D', year=2012, month=2,
  685. day=1).days_in_month == 29
  686. def test_properties_hourly(self):
  687. # Test properties on Periods with hourly frequency.
  688. h_date1 = Period(freq='H', year=2007, month=1, day=1, hour=0)
  689. h_date2 = Period(freq='2H', year=2007, month=1, day=1, hour=0)
  690. for h_date in [h_date1, h_date2]:
  691. assert h_date.year == 2007
  692. assert h_date.quarter == 1
  693. assert h_date.month == 1
  694. assert h_date.day == 1
  695. assert h_date.weekday == 0
  696. assert h_date.dayofyear == 1
  697. assert h_date.hour == 0
  698. assert h_date.days_in_month == 31
  699. assert Period(freq='H', year=2012, month=2, day=1,
  700. hour=0).days_in_month == 29
  701. def test_properties_minutely(self):
  702. # Test properties on Periods with minutely frequency.
  703. t_date = Period(freq='Min', year=2007, month=1, day=1, hour=0,
  704. minute=0)
  705. #
  706. assert t_date.quarter == 1
  707. assert t_date.month == 1
  708. assert t_date.day == 1
  709. assert t_date.weekday == 0
  710. assert t_date.dayofyear == 1
  711. assert t_date.hour == 0
  712. assert t_date.minute == 0
  713. assert t_date.days_in_month == 31
  714. assert Period(freq='D', year=2012, month=2, day=1, hour=0,
  715. minute=0).days_in_month == 29
  716. def test_properties_secondly(self):
  717. # Test properties on Periods with secondly frequency.
  718. s_date = Period(freq='Min', year=2007, month=1, day=1, hour=0,
  719. minute=0, second=0)
  720. #
  721. assert s_date.year == 2007
  722. assert s_date.quarter == 1
  723. assert s_date.month == 1
  724. assert s_date.day == 1
  725. assert s_date.weekday == 0
  726. assert s_date.dayofyear == 1
  727. assert s_date.hour == 0
  728. assert s_date.minute == 0
  729. assert s_date.second == 0
  730. assert s_date.days_in_month == 31
  731. assert Period(freq='Min', year=2012, month=2, day=1, hour=0,
  732. minute=0, second=0).days_in_month == 29
  733. class TestPeriodField(object):
  734. def test_get_period_field_array_raises_on_out_of_range(self):
  735. pytest.raises(ValueError, libperiod.get_period_field_arr, -1,
  736. np.empty(1), 0)
  737. class TestComparisons(object):
  738. def setup_method(self, method):
  739. self.january1 = Period('2000-01', 'M')
  740. self.january2 = Period('2000-01', 'M')
  741. self.february = Period('2000-02', 'M')
  742. self.march = Period('2000-03', 'M')
  743. self.day = Period('2012-01-01', 'D')
  744. def test_equal(self):
  745. assert self.january1 == self.january2
  746. def test_equal_Raises_Value(self):
  747. with pytest.raises(period.IncompatibleFrequency):
  748. self.january1 == self.day
  749. def test_notEqual(self):
  750. assert self.january1 != 1
  751. assert self.january1 != self.february
  752. def test_greater(self):
  753. assert self.february > self.january1
  754. def test_greater_Raises_Value(self):
  755. with pytest.raises(period.IncompatibleFrequency):
  756. self.january1 > self.day
  757. def test_greater_Raises_Type(self):
  758. with pytest.raises(TypeError):
  759. self.january1 > 1
  760. def test_greaterEqual(self):
  761. assert self.january1 >= self.january2
  762. def test_greaterEqual_Raises_Value(self):
  763. with pytest.raises(period.IncompatibleFrequency):
  764. self.january1 >= self.day
  765. with pytest.raises(TypeError):
  766. print(self.january1 >= 1)
  767. def test_smallerEqual(self):
  768. assert self.january1 <= self.january2
  769. def test_smallerEqual_Raises_Value(self):
  770. with pytest.raises(period.IncompatibleFrequency):
  771. self.january1 <= self.day
  772. def test_smallerEqual_Raises_Type(self):
  773. with pytest.raises(TypeError):
  774. self.january1 <= 1
  775. def test_smaller(self):
  776. assert self.january1 < self.february
  777. def test_smaller_Raises_Value(self):
  778. with pytest.raises(period.IncompatibleFrequency):
  779. self.january1 < self.day
  780. def test_smaller_Raises_Type(self):
  781. with pytest.raises(TypeError):
  782. self.january1 < 1
  783. def test_sort(self):
  784. periods = [self.march, self.january1, self.february]
  785. correctPeriods = [self.january1, self.february, self.march]
  786. assert sorted(periods) == correctPeriods
  787. def test_period_nat_comp(self):
  788. p_nat = Period('NaT', freq='D')
  789. p = Period('2011-01-01', freq='D')
  790. nat = Timestamp('NaT')
  791. t = Timestamp('2011-01-01')
  792. # confirm Period('NaT') work identical with Timestamp('NaT')
  793. for left, right in [(p_nat, p), (p, p_nat), (p_nat, p_nat), (nat, t),
  794. (t, nat), (nat, nat)]:
  795. assert not left < right
  796. assert not left > right
  797. assert not left == right
  798. assert left != right
  799. assert not left <= right
  800. assert not left >= right
  801. class TestArithmetic(object):
  802. def test_sub_delta(self):
  803. left, right = Period('2011', freq='A'), Period('2007', freq='A')
  804. result = left - right
  805. assert result == 4 * right.freq
  806. with pytest.raises(period.IncompatibleFrequency):
  807. left - Period('2007-01', freq='M')
  808. def test_add_integer(self):
  809. per1 = Period(freq='D', year=2008, month=1, day=1)
  810. per2 = Period(freq='D', year=2008, month=1, day=2)
  811. assert per1 + 1 == per2
  812. assert 1 + per1 == per2
  813. def test_add_sub_nat(self):
  814. # GH#13071
  815. p = Period('2011-01', freq='M')
  816. assert p + NaT is NaT
  817. assert NaT + p is NaT
  818. assert p - NaT is NaT
  819. assert NaT - p is NaT
  820. p = Period('NaT', freq='M')
  821. assert p + NaT is NaT
  822. assert NaT + p is NaT
  823. assert p - NaT is NaT
  824. assert NaT - p is NaT
  825. def test_add_invalid(self):
  826. # GH#4731
  827. per1 = Period(freq='D', year=2008, month=1, day=1)
  828. per2 = Period(freq='D', year=2008, month=1, day=2)
  829. msg = r"unsupported operand type\(s\)"
  830. with pytest.raises(TypeError, match=msg):
  831. per1 + "str"
  832. with pytest.raises(TypeError, match=msg):
  833. "str" + per1
  834. with pytest.raises(TypeError, match=msg):
  835. per1 + per2
  836. boxes = [lambda x: x, lambda x: pd.Series([x]), lambda x: pd.Index([x])]
  837. ids = ['identity', 'Series', 'Index']
  838. @pytest.mark.parametrize('lbox', boxes, ids=ids)
  839. @pytest.mark.parametrize('rbox', boxes, ids=ids)
  840. def test_add_timestamp_raises(self, rbox, lbox):
  841. # GH#17983
  842. ts = Timestamp('2017')
  843. per = Period('2017', freq='M')
  844. # We may get a different message depending on which class raises
  845. # the error.
  846. msg = (r"cannot add|unsupported operand|"
  847. r"can only operate on a|incompatible type|"
  848. r"ufunc add cannot use operands")
  849. with pytest.raises(TypeError, match=msg):
  850. lbox(ts) + rbox(per)
  851. with pytest.raises(TypeError, match=msg):
  852. lbox(per) + rbox(ts)
  853. with pytest.raises(TypeError, match=msg):
  854. lbox(per) + rbox(per)
  855. def test_sub(self):
  856. per1 = Period('2011-01-01', freq='D')
  857. per2 = Period('2011-01-15', freq='D')
  858. off = per1.freq
  859. assert per1 - per2 == -14 * off
  860. assert per2 - per1 == 14 * off
  861. msg = r"Input has different freq=M from Period\(freq=D\)"
  862. with pytest.raises(period.IncompatibleFrequency, match=msg):
  863. per1 - Period('2011-02', freq='M')
  864. @pytest.mark.parametrize('n', [1, 2, 3, 4])
  865. def test_sub_n_gt_1_ticks(self, tick_classes, n):
  866. # GH 23878
  867. p1 = pd.Period('19910905', freq=tick_classes(n))
  868. p2 = pd.Period('19920406', freq=tick_classes(n))
  869. expected = (pd.Period(str(p2), freq=p2.freq.base)
  870. - pd.Period(str(p1), freq=p1.freq.base))
  871. assert (p2 - p1) == expected
  872. @pytest.mark.parametrize('normalize', [True, False])
  873. @pytest.mark.parametrize('n', [1, 2, 3, 4])
  874. @pytest.mark.parametrize('offset, kwd_name', [
  875. (pd.offsets.YearEnd, 'month'),
  876. (pd.offsets.QuarterEnd, 'startingMonth'),
  877. (pd.offsets.MonthEnd, None),
  878. (pd.offsets.Week, 'weekday')
  879. ])
  880. def test_sub_n_gt_1_offsets(self, offset, kwd_name, n, normalize):
  881. # GH 23878
  882. kwds = {kwd_name: 3} if kwd_name is not None else {}
  883. p1_d = '19910905'
  884. p2_d = '19920406'
  885. p1 = pd.Period(p1_d, freq=offset(n, normalize, **kwds))
  886. p2 = pd.Period(p2_d, freq=offset(n, normalize, **kwds))
  887. expected = (pd.Period(p2_d, freq=p2.freq.base)
  888. - pd.Period(p1_d, freq=p1.freq.base))
  889. assert (p2 - p1) == expected
  890. def test_add_offset(self):
  891. # freq is DateOffset
  892. for freq in ['A', '2A', '3A']:
  893. p = Period('2011', freq=freq)
  894. exp = Period('2013', freq=freq)
  895. assert p + offsets.YearEnd(2) == exp
  896. assert offsets.YearEnd(2) + p == exp
  897. for o in [offsets.YearBegin(2), offsets.MonthBegin(1),
  898. offsets.Minute(), np.timedelta64(365, 'D'),
  899. timedelta(365)]:
  900. with pytest.raises(period.IncompatibleFrequency):
  901. p + o
  902. if isinstance(o, np.timedelta64):
  903. with pytest.raises(TypeError):
  904. o + p
  905. else:
  906. with pytest.raises(period.IncompatibleFrequency):
  907. o + p
  908. for freq in ['M', '2M', '3M']:
  909. p = Period('2011-03', freq=freq)
  910. exp = Period('2011-05', freq=freq)
  911. assert p + offsets.MonthEnd(2) == exp
  912. assert offsets.MonthEnd(2) + p == exp
  913. exp = Period('2012-03', freq=freq)
  914. assert p + offsets.MonthEnd(12) == exp
  915. assert offsets.MonthEnd(12) + p == exp
  916. for o in [offsets.YearBegin(2), offsets.MonthBegin(1),
  917. offsets.Minute(), np.timedelta64(365, 'D'),
  918. timedelta(365)]:
  919. with pytest.raises(period.IncompatibleFrequency):
  920. p + o
  921. if isinstance(o, np.timedelta64):
  922. with pytest.raises(TypeError):
  923. o + p
  924. else:
  925. with pytest.raises(period.IncompatibleFrequency):
  926. o + p
  927. # freq is Tick
  928. for freq in ['D', '2D', '3D']:
  929. p = Period('2011-04-01', freq=freq)
  930. exp = Period('2011-04-06', freq=freq)
  931. assert p + offsets.Day(5) == exp
  932. assert offsets.Day(5) + p == exp
  933. exp = Period('2011-04-02', freq=freq)
  934. assert p + offsets.Hour(24) == exp
  935. assert offsets.Hour(24) + p == exp
  936. exp = Period('2011-04-03', freq=freq)
  937. assert p + np.timedelta64(2, 'D') == exp
  938. with pytest.raises(TypeError):
  939. np.timedelta64(2, 'D') + p
  940. exp = Period('2011-04-02', freq=freq)
  941. assert p + np.timedelta64(3600 * 24, 's') == exp
  942. with pytest.raises(TypeError):
  943. np.timedelta64(3600 * 24, 's') + p
  944. exp = Period('2011-03-30', freq=freq)
  945. assert p + timedelta(-2) == exp
  946. assert timedelta(-2) + p == exp
  947. exp = Period('2011-04-03', freq=freq)
  948. assert p + timedelta(hours=48) == exp
  949. assert timedelta(hours=48) + p == exp
  950. for o in [offsets.YearBegin(2), offsets.MonthBegin(1),
  951. offsets.Minute(), np.timedelta64(4, 'h'),
  952. timedelta(hours=23)]:
  953. with pytest.raises(period.IncompatibleFrequency):
  954. p + o
  955. if isinstance(o, np.timedelta64):
  956. with pytest.raises(TypeError):
  957. o + p
  958. else:
  959. with pytest.raises(period.IncompatibleFrequency):
  960. o + p
  961. for freq in ['H', '2H', '3H']:
  962. p = Period('2011-04-01 09:00', freq=freq)
  963. exp = Period('2011-04-03 09:00', freq=freq)
  964. assert p + offsets.Day(2) == exp
  965. assert offsets.Day(2) + p == exp
  966. exp = Period('2011-04-01 12:00', freq=freq)
  967. assert p + offsets.Hour(3) == exp
  968. assert offsets.Hour(3) + p == exp
  969. exp = Period('2011-04-01 12:00', freq=freq)
  970. assert p + np.timedelta64(3, 'h') == exp
  971. with pytest.raises(TypeError):
  972. np.timedelta64(3, 'h') + p
  973. exp = Period('2011-04-01 10:00', freq=freq)
  974. assert p + np.timedelta64(3600, 's') == exp
  975. with pytest.raises(TypeError):
  976. np.timedelta64(3600, 's') + p
  977. exp = Period('2011-04-01 11:00', freq=freq)
  978. assert p + timedelta(minutes=120) == exp
  979. assert timedelta(minutes=120) + p == exp
  980. exp = Period('2011-04-05 12:00', freq=freq)
  981. assert p + timedelta(days=4, minutes=180) == exp
  982. assert timedelta(days=4, minutes=180) + p == exp
  983. for o in [offsets.YearBegin(2), offsets.MonthBegin(1),
  984. offsets.Minute(), np.timedelta64(3200, 's'),
  985. timedelta(hours=23, minutes=30)]:
  986. with pytest.raises(period.IncompatibleFrequency):
  987. p + o
  988. if isinstance(o, np.timedelta64):
  989. with pytest.raises(TypeError):
  990. o + p
  991. else:
  992. with pytest.raises(period.IncompatibleFrequency):
  993. o + p
  994. def test_add_offset_nat(self):
  995. # freq is DateOffset
  996. for freq in ['A', '2A', '3A']:
  997. p = Period('NaT', freq=freq)
  998. for o in [offsets.YearEnd(2)]:
  999. assert p + o is NaT
  1000. assert o + p is NaT
  1001. for o in [offsets.YearBegin(2), offsets.MonthBegin(1),
  1002. offsets.Minute(), np.timedelta64(365, 'D'),
  1003. timedelta(365)]:
  1004. assert p + o is NaT
  1005. if isinstance(o, np.timedelta64):
  1006. with pytest.raises(TypeError):
  1007. o + p
  1008. else:
  1009. assert o + p is NaT
  1010. for freq in ['M', '2M', '3M']:
  1011. p = Period('NaT', freq=freq)
  1012. for o in [offsets.MonthEnd(2), offsets.MonthEnd(12)]:
  1013. assert p + o is NaT
  1014. if isinstance(o, np.timedelta64):
  1015. with pytest.raises(TypeError):
  1016. o + p
  1017. else:
  1018. assert o + p is NaT
  1019. for o in [offsets.YearBegin(2), offsets.MonthBegin(1),
  1020. offsets.Minute(), np.timedelta64(365, 'D'),
  1021. timedelta(365)]:
  1022. assert p + o is NaT
  1023. if isinstance(o, np.timedelta64):
  1024. with pytest.raises(TypeError):
  1025. o + p
  1026. else:
  1027. assert o + p is NaT
  1028. # freq is Tick
  1029. for freq in ['D', '2D', '3D']:
  1030. p = Period('NaT', freq=freq)
  1031. for o in [offsets.Day(5), offsets.Hour(24), np.timedelta64(2, 'D'),
  1032. np.timedelta64(3600 * 24, 's'), timedelta(-2),
  1033. timedelta(hours=48)]:
  1034. assert p + o is NaT
  1035. if isinstance(o, np.timedelta64):
  1036. with pytest.raises(TypeError):
  1037. o + p
  1038. else:
  1039. assert o + p is NaT
  1040. for o in [offsets.YearBegin(2), offsets.MonthBegin(1),
  1041. offsets.Minute(), np.timedelta64(4, 'h'),
  1042. timedelta(hours=23)]:
  1043. assert p + o is NaT
  1044. if isinstance(o, np.timedelta64):
  1045. with pytest.raises(TypeError):
  1046. o + p
  1047. else:
  1048. assert o + p is NaT
  1049. for freq in ['H', '2H', '3H']:
  1050. p = Period('NaT', freq=freq)
  1051. for o in [offsets.Day(2), offsets.Hour(3), np.timedelta64(3, 'h'),
  1052. np.timedelta64(3600, 's'), timedelta(minutes=120),
  1053. timedelta(days=4, minutes=180)]:
  1054. assert p + o is NaT
  1055. if not isinstance(o, np.timedelta64):
  1056. assert o + p is NaT
  1057. for o in [offsets.YearBegin(2), offsets.MonthBegin(1),
  1058. offsets.Minute(), np.timedelta64(3200, 's'),
  1059. timedelta(hours=23, minutes=30)]:
  1060. assert p + o is NaT
  1061. if isinstance(o, np.timedelta64):
  1062. with pytest.raises(TypeError):
  1063. o + p
  1064. else:
  1065. assert o + p is NaT
  1066. def test_sub_offset(self):
  1067. # freq is DateOffset
  1068. for freq in ['A', '2A', '3A']:
  1069. p = Period('2011', freq=freq)
  1070. assert p - offsets.YearEnd(2) == Period('2009', freq=freq)
  1071. for o in [offsets.YearBegin(2), offsets.MonthBegin(1),
  1072. offsets.Minute(), np.timedelta64(365, 'D'),
  1073. timedelta(365)]:
  1074. with pytest.raises(period.IncompatibleFrequency):
  1075. p - o
  1076. for freq in ['M', '2M', '3M']:
  1077. p = Period('2011-03', freq=freq)
  1078. assert p - offsets.MonthEnd(2) == Period('2011-01', freq=freq)
  1079. assert p - offsets.MonthEnd(12) == Period('2010-03', freq=freq)
  1080. for o in [offsets.YearBegin(2), offsets.MonthBegin(1),
  1081. offsets.Minute(), np.timedelta64(365, 'D'),
  1082. timedelta(365)]:
  1083. with pytest.raises(period.IncompatibleFrequency):
  1084. p - o
  1085. # freq is Tick
  1086. for freq in ['D', '2D', '3D']:
  1087. p = Period('2011-04-01', freq=freq)
  1088. assert p - offsets.Day(5) == Period('2011-03-27', freq=freq)
  1089. assert p - offsets.Hour(24) == Period('2011-03-31', freq=freq)
  1090. assert p - np.timedelta64(2, 'D') == Period(
  1091. '2011-03-30', freq=freq)
  1092. assert p - np.timedelta64(3600 * 24, 's') == Period(
  1093. '2011-03-31', freq=freq)
  1094. assert p - timedelta(-2) == Period('2011-04-03', freq=freq)
  1095. assert p - timedelta(hours=48) == Period('2011-03-30', freq=freq)
  1096. for o in [offsets.YearBegin(2), offsets.MonthBegin(1),
  1097. offsets.Minute(), np.timedelta64(4, 'h'),
  1098. timedelta(hours=23)]:
  1099. with pytest.raises(period.IncompatibleFrequency):
  1100. p - o
  1101. for freq in ['H', '2H', '3H']:
  1102. p = Period('2011-04-01 09:00', freq=freq)
  1103. assert p - offsets.Day(2) == Period('2011-03-30 09:00', freq=freq)
  1104. assert p - offsets.Hour(3) == Period('2011-04-01 06:00', freq=freq)
  1105. assert p - np.timedelta64(3, 'h') == Period(
  1106. '2011-04-01 06:00', freq=freq)
  1107. assert p - np.timedelta64(3600, 's') == Period(
  1108. '2011-04-01 08:00', freq=freq)
  1109. assert p - timedelta(minutes=120) == Period(
  1110. '2011-04-01 07:00', freq=freq)
  1111. assert p - timedelta(days=4, minutes=180) == Period(
  1112. '2011-03-28 06:00', freq=freq)
  1113. for o in [offsets.YearBegin(2), offsets.MonthBegin(1),
  1114. offsets.Minute(), np.timedelta64(3200, 's'),
  1115. timedelta(hours=23, minutes=30)]:
  1116. with pytest.raises(period.IncompatibleFrequency):
  1117. p - o
  1118. def test_sub_offset_nat(self):
  1119. # freq is DateOffset
  1120. for freq in ['A', '2A', '3A']:
  1121. p = Period('NaT', freq=freq)
  1122. for o in [offsets.YearEnd(2)]:
  1123. assert p - o is NaT
  1124. for o in [offsets.YearBegin(2), offsets.MonthBegin(1),
  1125. offsets.Minute(), np.timedelta64(365, 'D'),
  1126. timedelta(365)]:
  1127. assert p - o is NaT
  1128. for freq in ['M', '2M', '3M']:
  1129. p = Period('NaT', freq=freq)
  1130. for o in [offsets.MonthEnd(2), offsets.MonthEnd(12)]:
  1131. assert p - o is NaT
  1132. for o in [offsets.YearBegin(2), offsets.MonthBegin(1),
  1133. offsets.Minute(), np.timedelta64(365, 'D'),
  1134. timedelta(365)]:
  1135. assert p - o is NaT
  1136. # freq is Tick
  1137. for freq in ['D', '2D', '3D']:
  1138. p = Period('NaT', freq=freq)
  1139. for o in [offsets.Day(5), offsets.Hour(24), np.timedelta64(2, 'D'),
  1140. np.timedelta64(3600 * 24, 's'), timedelta(-2),
  1141. timedelta(hours=48)]:
  1142. assert p - o is NaT
  1143. for o in [offsets.YearBegin(2), offsets.MonthBegin(1),
  1144. offsets.Minute(), np.timedelta64(4, 'h'),
  1145. timedelta(hours=23)]:
  1146. assert p - o is NaT
  1147. for freq in ['H', '2H', '3H']:
  1148. p = Period('NaT', freq=freq)
  1149. for o in [offsets.Day(2), offsets.Hour(3), np.timedelta64(3, 'h'),
  1150. np.timedelta64(3600, 's'), timedelta(minutes=120),
  1151. timedelta(days=4, minutes=180)]:
  1152. assert p - o is NaT
  1153. for o in [offsets.YearBegin(2), offsets.MonthBegin(1),
  1154. offsets.Minute(), np.timedelta64(3200, 's'),
  1155. timedelta(hours=23, minutes=30)]:
  1156. assert p - o is NaT
  1157. @pytest.mark.parametrize('freq', ['M', '2M', '3M'])
  1158. def test_nat_ops(self, freq):
  1159. p = Period('NaT', freq=freq)
  1160. assert p + 1 is NaT
  1161. assert 1 + p is NaT
  1162. assert p - 1 is NaT
  1163. assert p - Period('2011-01', freq=freq) is NaT
  1164. assert Period('2011-01', freq=freq) - p is NaT
  1165. def test_period_ops_offset(self):
  1166. p = Period('2011-04-01', freq='D')
  1167. result = p + offsets.Day()
  1168. exp = Period('2011-04-02', freq='D')
  1169. assert result == exp
  1170. result = p - offsets.Day(2)
  1171. exp = Period('2011-03-30', freq='D')
  1172. assert result == exp
  1173. msg = r"Input cannot be converted to Period\(freq=D\)"
  1174. with pytest.raises(period.IncompatibleFrequency, match=msg):
  1175. p + offsets.Hour(2)
  1176. with pytest.raises(period.IncompatibleFrequency, match=msg):
  1177. p - offsets.Hour(2)
  1178. def test_period_immutable():
  1179. # see gh-17116
  1180. per = Period('2014Q1')
  1181. with pytest.raises(AttributeError):
  1182. per.ordinal = 14
  1183. freq = per.freq
  1184. with pytest.raises(AttributeError):
  1185. per.freq = 2 * freq
  1186. # TODO: This doesn't fail on all systems; track down which
  1187. @pytest.mark.xfail(reason="Parses as Jan 1, 0007 on some systems",
  1188. strict=False)
  1189. def test_small_year_parsing():
  1190. per1 = Period('0001-01-07', 'D')
  1191. assert per1.year == 1
  1192. assert per1.day == 7