PageRenderTime 88ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 1ms

/pandas/tseries/tests/test_offsets.py

http://github.com/wesm/pandas
Python | 4923 lines | 3895 code | 871 blank | 157 comment | 231 complexity | 2ab5f86d3cceca3f0ae7857b00894086 MD5 | raw file
Possible License(s): BSD-3-Clause, Apache-2.0
  1. import os
  2. from datetime import date, datetime, timedelta
  3. from dateutil.relativedelta import relativedelta
  4. from pandas.compat import range, iteritems
  5. from pandas import compat
  6. import nose
  7. from nose.tools import assert_raises
  8. import numpy as np
  9. from pandas.compat.numpy import np_datetime64_compat
  10. from pandas.core.datetools import (bday, BDay, CDay, BQuarterEnd, BMonthEnd,
  11. BusinessHour, CustomBusinessHour,
  12. CBMonthEnd, CBMonthBegin, BYearEnd,
  13. MonthEnd, MonthBegin, SemiMonthBegin,
  14. SemiMonthEnd, BYearBegin, QuarterBegin,
  15. BQuarterBegin, BMonthBegin, DateOffset,
  16. Week, YearBegin, YearEnd, Hour, Minute,
  17. Second, Day, Micro, Milli, Nano, Easter,
  18. WeekOfMonth, format, ole2datetime,
  19. QuarterEnd, to_datetime, normalize_date,
  20. get_offset, get_standard_freq)
  21. from pandas.core.series import Series
  22. from pandas.tseries.frequencies import (_offset_map, get_freq_code,
  23. _get_freq_str, _INVALID_FREQ_ERROR)
  24. from pandas.tseries.index import _to_m8, DatetimeIndex, _daterange_cache
  25. from pandas.tseries.tools import parse_time_string, DateParseError
  26. import pandas.tseries.offsets as offsets
  27. from pandas.io.pickle import read_pickle
  28. from pandas.tslib import NaT, Timestamp, Timedelta
  29. import pandas.tslib as tslib
  30. from pandas.util.testing import assertRaisesRegexp
  31. import pandas.util.testing as tm
  32. from pandas.tseries.offsets import BusinessMonthEnd, CacheableOffset, \
  33. LastWeekOfMonth, FY5253, FY5253Quarter, WeekDay
  34. from pandas.tseries.holiday import USFederalHolidayCalendar
  35. _multiprocess_can_split_ = True
  36. def test_monthrange():
  37. import calendar
  38. for y in range(2000, 2013):
  39. for m in range(1, 13):
  40. assert tslib.monthrange(y, m) == calendar.monthrange(y, m)
  41. ####
  42. # Misc function tests
  43. ####
  44. def test_format():
  45. actual = format(datetime(2008, 1, 15))
  46. assert actual == '20080115'
  47. def test_ole2datetime():
  48. actual = ole2datetime(60000)
  49. assert actual == datetime(2064, 4, 8)
  50. assert_raises(ValueError, ole2datetime, 60)
  51. def test_to_datetime1():
  52. actual = to_datetime(datetime(2008, 1, 15))
  53. assert actual == datetime(2008, 1, 15)
  54. actual = to_datetime('20080115')
  55. assert actual == datetime(2008, 1, 15)
  56. # unparseable
  57. s = 'Month 1, 1999'
  58. assert to_datetime(s, errors='ignore') == s
  59. def test_normalize_date():
  60. actual = normalize_date(datetime(2007, 10, 1, 1, 12, 5, 10))
  61. assert actual == datetime(2007, 10, 1)
  62. def test_to_m8():
  63. valb = datetime(2007, 10, 1)
  64. valu = _to_m8(valb)
  65. tm.assertIsInstance(valu, np.datetime64)
  66. # assert valu == np.datetime64(datetime(2007,10,1))
  67. # def test_datetime64_box():
  68. # valu = np.datetime64(datetime(2007,10,1))
  69. # valb = _dt_box(valu)
  70. # assert type(valb) == datetime
  71. # assert valb == datetime(2007,10,1)
  72. #####
  73. # DateOffset Tests
  74. #####
  75. class Base(tm.TestCase):
  76. _offset = None
  77. _offset_types = [getattr(offsets, o) for o in offsets.__all__]
  78. timezones = [None, 'UTC', 'Asia/Tokyo', 'US/Eastern',
  79. 'dateutil/Asia/Tokyo', 'dateutil/US/Pacific']
  80. @property
  81. def offset_types(self):
  82. return self._offset_types
  83. def _get_offset(self, klass, value=1, normalize=False):
  84. # create instance from offset class
  85. if klass is FY5253 or klass is FY5253Quarter:
  86. klass = klass(n=value, startingMonth=1, weekday=1,
  87. qtr_with_extra_week=1, variation='last',
  88. normalize=normalize)
  89. elif klass is LastWeekOfMonth:
  90. klass = klass(n=value, weekday=5, normalize=normalize)
  91. elif klass is WeekOfMonth:
  92. klass = klass(n=value, week=1, weekday=5, normalize=normalize)
  93. elif klass is Week:
  94. klass = klass(n=value, weekday=5, normalize=normalize)
  95. elif klass is DateOffset:
  96. klass = klass(days=value, normalize=normalize)
  97. else:
  98. try:
  99. klass = klass(value, normalize=normalize)
  100. except:
  101. klass = klass(normalize=normalize)
  102. return klass
  103. def test_apply_out_of_range(self):
  104. if self._offset is None:
  105. return
  106. # try to create an out-of-bounds result timestamp; if we can't create
  107. # the offset skip
  108. try:
  109. if self._offset in (BusinessHour, CustomBusinessHour):
  110. # Using 10000 in BusinessHour fails in tz check because of DST
  111. # difference
  112. offset = self._get_offset(self._offset, value=100000)
  113. else:
  114. offset = self._get_offset(self._offset, value=10000)
  115. result = Timestamp('20080101') + offset
  116. self.assertIsInstance(result, datetime)
  117. self.assertIsNone(result.tzinfo)
  118. tm._skip_if_no_pytz()
  119. tm._skip_if_no_dateutil()
  120. # Check tz is preserved
  121. for tz in self.timezones:
  122. t = Timestamp('20080101', tz=tz)
  123. result = t + offset
  124. self.assertIsInstance(result, datetime)
  125. self.assertEqual(t.tzinfo, result.tzinfo)
  126. except (tslib.OutOfBoundsDatetime):
  127. raise
  128. except (ValueError, KeyError) as e:
  129. raise nose.SkipTest(
  130. "cannot create out_of_range offset: {0} {1}".format(
  131. str(self).split('.')[-1], e))
  132. class TestCommon(Base):
  133. def setUp(self):
  134. # exected value created by Base._get_offset
  135. # are applied to 2011/01/01 09:00 (Saturday)
  136. # used for .apply and .rollforward
  137. self.expecteds = {'Day': Timestamp('2011-01-02 09:00:00'),
  138. 'DateOffset': Timestamp('2011-01-02 09:00:00'),
  139. 'BusinessDay': Timestamp('2011-01-03 09:00:00'),
  140. 'CustomBusinessDay':
  141. Timestamp('2011-01-03 09:00:00'),
  142. 'CustomBusinessMonthEnd':
  143. Timestamp('2011-01-31 09:00:00'),
  144. 'CustomBusinessMonthBegin':
  145. Timestamp('2011-01-03 09:00:00'),
  146. 'MonthBegin': Timestamp('2011-02-01 09:00:00'),
  147. 'BusinessMonthBegin':
  148. Timestamp('2011-01-03 09:00:00'),
  149. 'MonthEnd': Timestamp('2011-01-31 09:00:00'),
  150. 'SemiMonthEnd': Timestamp('2011-01-15 09:00:00'),
  151. 'SemiMonthBegin': Timestamp('2011-01-15 09:00:00'),
  152. 'BusinessMonthEnd': Timestamp('2011-01-31 09:00:00'),
  153. 'YearBegin': Timestamp('2012-01-01 09:00:00'),
  154. 'BYearBegin': Timestamp('2011-01-03 09:00:00'),
  155. 'YearEnd': Timestamp('2011-12-31 09:00:00'),
  156. 'BYearEnd': Timestamp('2011-12-30 09:00:00'),
  157. 'QuarterBegin': Timestamp('2011-03-01 09:00:00'),
  158. 'BQuarterBegin': Timestamp('2011-03-01 09:00:00'),
  159. 'QuarterEnd': Timestamp('2011-03-31 09:00:00'),
  160. 'BQuarterEnd': Timestamp('2011-03-31 09:00:00'),
  161. 'BusinessHour': Timestamp('2011-01-03 10:00:00'),
  162. 'CustomBusinessHour':
  163. Timestamp('2011-01-03 10:00:00'),
  164. 'WeekOfMonth': Timestamp('2011-01-08 09:00:00'),
  165. 'LastWeekOfMonth': Timestamp('2011-01-29 09:00:00'),
  166. 'FY5253Quarter': Timestamp('2011-01-25 09:00:00'),
  167. 'FY5253': Timestamp('2011-01-25 09:00:00'),
  168. 'Week': Timestamp('2011-01-08 09:00:00'),
  169. 'Easter': Timestamp('2011-04-24 09:00:00'),
  170. 'Hour': Timestamp('2011-01-01 10:00:00'),
  171. 'Minute': Timestamp('2011-01-01 09:01:00'),
  172. 'Second': Timestamp('2011-01-01 09:00:01'),
  173. 'Milli': Timestamp('2011-01-01 09:00:00.001000'),
  174. 'Micro': Timestamp('2011-01-01 09:00:00.000001'),
  175. 'Nano': Timestamp(np_datetime64_compat(
  176. '2011-01-01T09:00:00.000000001Z'))}
  177. def test_return_type(self):
  178. for offset in self.offset_types:
  179. offset = self._get_offset(offset)
  180. # make sure that we are returning a Timestamp
  181. result = Timestamp('20080101') + offset
  182. self.assertIsInstance(result, Timestamp)
  183. # make sure that we are returning NaT
  184. self.assertTrue(NaT + offset is NaT)
  185. self.assertTrue(offset + NaT is NaT)
  186. self.assertTrue(NaT - offset is NaT)
  187. self.assertTrue((-offset).apply(NaT) is NaT)
  188. def test_offset_n(self):
  189. for offset_klass in self.offset_types:
  190. offset = self._get_offset(offset_klass)
  191. self.assertEqual(offset.n, 1)
  192. neg_offset = offset * -1
  193. self.assertEqual(neg_offset.n, -1)
  194. mul_offset = offset * 3
  195. self.assertEqual(mul_offset.n, 3)
  196. def test_offset_freqstr(self):
  197. for offset_klass in self.offset_types:
  198. offset = self._get_offset(offset_klass)
  199. freqstr = offset.freqstr
  200. if freqstr not in ('<Easter>',
  201. "<DateOffset: kwds={'days': 1}>",
  202. 'LWOM-SAT', ):
  203. code = get_offset(freqstr)
  204. self.assertEqual(offset.rule_code, code)
  205. def _check_offsetfunc_works(self, offset, funcname, dt, expected,
  206. normalize=False):
  207. offset_s = self._get_offset(offset, normalize=normalize)
  208. func = getattr(offset_s, funcname)
  209. result = func(dt)
  210. self.assertTrue(isinstance(result, Timestamp))
  211. self.assertEqual(result, expected)
  212. result = func(Timestamp(dt))
  213. self.assertTrue(isinstance(result, Timestamp))
  214. self.assertEqual(result, expected)
  215. # test nano second is preserved
  216. result = func(Timestamp(dt) + Nano(5))
  217. self.assertTrue(isinstance(result, Timestamp))
  218. if normalize is False:
  219. self.assertEqual(result, expected + Nano(5))
  220. else:
  221. self.assertEqual(result, expected)
  222. if isinstance(dt, np.datetime64):
  223. # test tz when input is datetime or Timestamp
  224. return
  225. tm._skip_if_no_pytz()
  226. tm._skip_if_no_dateutil()
  227. for tz in self.timezones:
  228. expected_localize = expected.tz_localize(tz)
  229. tz_obj = tslib.maybe_get_tz(tz)
  230. dt_tz = tslib._localize_pydatetime(dt, tz_obj)
  231. result = func(dt_tz)
  232. self.assertTrue(isinstance(result, Timestamp))
  233. self.assertEqual(result, expected_localize)
  234. result = func(Timestamp(dt, tz=tz))
  235. self.assertTrue(isinstance(result, Timestamp))
  236. self.assertEqual(result, expected_localize)
  237. # test nano second is preserved
  238. result = func(Timestamp(dt, tz=tz) + Nano(5))
  239. self.assertTrue(isinstance(result, Timestamp))
  240. if normalize is False:
  241. self.assertEqual(result, expected_localize + Nano(5))
  242. else:
  243. self.assertEqual(result, expected_localize)
  244. def test_apply(self):
  245. sdt = datetime(2011, 1, 1, 9, 0)
  246. ndt = np_datetime64_compat('2011-01-01 09:00Z')
  247. for offset in self.offset_types:
  248. for dt in [sdt, ndt]:
  249. expected = self.expecteds[offset.__name__]
  250. self._check_offsetfunc_works(offset, 'apply', dt, expected)
  251. expected = Timestamp(expected.date())
  252. self._check_offsetfunc_works(offset, 'apply', dt, expected,
  253. normalize=True)
  254. def test_rollforward(self):
  255. expecteds = self.expecteds.copy()
  256. # result will not be changed if the target is on the offset
  257. no_changes = ['Day', 'MonthBegin', 'SemiMonthBegin', 'YearBegin',
  258. 'Week', 'Hour', 'Minute', 'Second', 'Milli', 'Micro',
  259. 'Nano', 'DateOffset']
  260. for n in no_changes:
  261. expecteds[n] = Timestamp('2011/01/01 09:00')
  262. expecteds['BusinessHour'] = Timestamp('2011-01-03 09:00:00')
  263. expecteds['CustomBusinessHour'] = Timestamp('2011-01-03 09:00:00')
  264. # but be changed when normalize=True
  265. norm_expected = expecteds.copy()
  266. for k in norm_expected:
  267. norm_expected[k] = Timestamp(norm_expected[k].date())
  268. normalized = {'Day': Timestamp('2011-01-02 00:00:00'),
  269. 'DateOffset': Timestamp('2011-01-02 00:00:00'),
  270. 'MonthBegin': Timestamp('2011-02-01 00:00:00'),
  271. 'SemiMonthBegin': Timestamp('2011-01-15 00:00:00'),
  272. 'YearBegin': Timestamp('2012-01-01 00:00:00'),
  273. 'Week': Timestamp('2011-01-08 00:00:00'),
  274. 'Hour': Timestamp('2011-01-01 00:00:00'),
  275. 'Minute': Timestamp('2011-01-01 00:00:00'),
  276. 'Second': Timestamp('2011-01-01 00:00:00'),
  277. 'Milli': Timestamp('2011-01-01 00:00:00'),
  278. 'Micro': Timestamp('2011-01-01 00:00:00')}
  279. norm_expected.update(normalized)
  280. sdt = datetime(2011, 1, 1, 9, 0)
  281. ndt = np_datetime64_compat('2011-01-01 09:00Z')
  282. for offset in self.offset_types:
  283. for dt in [sdt, ndt]:
  284. expected = expecteds[offset.__name__]
  285. self._check_offsetfunc_works(offset, 'rollforward', dt,
  286. expected)
  287. expected = norm_expected[offset.__name__]
  288. self._check_offsetfunc_works(offset, 'rollforward', dt,
  289. expected, normalize=True)
  290. def test_rollback(self):
  291. expecteds = {'BusinessDay': Timestamp('2010-12-31 09:00:00'),
  292. 'CustomBusinessDay': Timestamp('2010-12-31 09:00:00'),
  293. 'CustomBusinessMonthEnd':
  294. Timestamp('2010-12-31 09:00:00'),
  295. 'CustomBusinessMonthBegin':
  296. Timestamp('2010-12-01 09:00:00'),
  297. 'BusinessMonthBegin': Timestamp('2010-12-01 09:00:00'),
  298. 'MonthEnd': Timestamp('2010-12-31 09:00:00'),
  299. 'SemiMonthEnd': Timestamp('2010-12-31 09:00:00'),
  300. 'BusinessMonthEnd': Timestamp('2010-12-31 09:00:00'),
  301. 'BYearBegin': Timestamp('2010-01-01 09:00:00'),
  302. 'YearEnd': Timestamp('2010-12-31 09:00:00'),
  303. 'BYearEnd': Timestamp('2010-12-31 09:00:00'),
  304. 'QuarterBegin': Timestamp('2010-12-01 09:00:00'),
  305. 'BQuarterBegin': Timestamp('2010-12-01 09:00:00'),
  306. 'QuarterEnd': Timestamp('2010-12-31 09:00:00'),
  307. 'BQuarterEnd': Timestamp('2010-12-31 09:00:00'),
  308. 'BusinessHour': Timestamp('2010-12-31 17:00:00'),
  309. 'CustomBusinessHour': Timestamp('2010-12-31 17:00:00'),
  310. 'WeekOfMonth': Timestamp('2010-12-11 09:00:00'),
  311. 'LastWeekOfMonth': Timestamp('2010-12-25 09:00:00'),
  312. 'FY5253Quarter': Timestamp('2010-10-26 09:00:00'),
  313. 'FY5253': Timestamp('2010-01-26 09:00:00'),
  314. 'Easter': Timestamp('2010-04-04 09:00:00')}
  315. # result will not be changed if the target is on the offset
  316. for n in ['Day', 'MonthBegin', 'SemiMonthBegin', 'YearBegin', 'Week',
  317. 'Hour', 'Minute', 'Second', 'Milli', 'Micro', 'Nano',
  318. 'DateOffset']:
  319. expecteds[n] = Timestamp('2011/01/01 09:00')
  320. # but be changed when normalize=True
  321. norm_expected = expecteds.copy()
  322. for k in norm_expected:
  323. norm_expected[k] = Timestamp(norm_expected[k].date())
  324. normalized = {'Day': Timestamp('2010-12-31 00:00:00'),
  325. 'DateOffset': Timestamp('2010-12-31 00:00:00'),
  326. 'MonthBegin': Timestamp('2010-12-01 00:00:00'),
  327. 'SemiMonthBegin': Timestamp('2010-12-15 00:00:00'),
  328. 'YearBegin': Timestamp('2010-01-01 00:00:00'),
  329. 'Week': Timestamp('2010-12-25 00:00:00'),
  330. 'Hour': Timestamp('2011-01-01 00:00:00'),
  331. 'Minute': Timestamp('2011-01-01 00:00:00'),
  332. 'Second': Timestamp('2011-01-01 00:00:00'),
  333. 'Milli': Timestamp('2011-01-01 00:00:00'),
  334. 'Micro': Timestamp('2011-01-01 00:00:00')}
  335. norm_expected.update(normalized)
  336. sdt = datetime(2011, 1, 1, 9, 0)
  337. ndt = np_datetime64_compat('2011-01-01 09:00Z')
  338. for offset in self.offset_types:
  339. for dt in [sdt, ndt]:
  340. expected = expecteds[offset.__name__]
  341. self._check_offsetfunc_works(offset, 'rollback', dt, expected)
  342. expected = norm_expected[offset.__name__]
  343. self._check_offsetfunc_works(offset, 'rollback', dt, expected,
  344. normalize=True)
  345. def test_onOffset(self):
  346. for offset in self.offset_types:
  347. dt = self.expecteds[offset.__name__]
  348. offset_s = self._get_offset(offset)
  349. self.assertTrue(offset_s.onOffset(dt))
  350. # when normalize=True, onOffset checks time is 00:00:00
  351. offset_n = self._get_offset(offset, normalize=True)
  352. self.assertFalse(offset_n.onOffset(dt))
  353. if offset in (BusinessHour, CustomBusinessHour):
  354. # In default BusinessHour (9:00-17:00), normalized time
  355. # cannot be in business hour range
  356. continue
  357. date = datetime(dt.year, dt.month, dt.day)
  358. self.assertTrue(offset_n.onOffset(date))
  359. def test_add(self):
  360. dt = datetime(2011, 1, 1, 9, 0)
  361. for offset in self.offset_types:
  362. offset_s = self._get_offset(offset)
  363. expected = self.expecteds[offset.__name__]
  364. result_dt = dt + offset_s
  365. result_ts = Timestamp(dt) + offset_s
  366. for result in [result_dt, result_ts]:
  367. self.assertTrue(isinstance(result, Timestamp))
  368. self.assertEqual(result, expected)
  369. tm._skip_if_no_pytz()
  370. for tz in self.timezones:
  371. expected_localize = expected.tz_localize(tz)
  372. result = Timestamp(dt, tz=tz) + offset_s
  373. self.assertTrue(isinstance(result, Timestamp))
  374. self.assertEqual(result, expected_localize)
  375. # normalize=True
  376. offset_s = self._get_offset(offset, normalize=True)
  377. expected = Timestamp(expected.date())
  378. result_dt = dt + offset_s
  379. result_ts = Timestamp(dt) + offset_s
  380. for result in [result_dt, result_ts]:
  381. self.assertTrue(isinstance(result, Timestamp))
  382. self.assertEqual(result, expected)
  383. for tz in self.timezones:
  384. expected_localize = expected.tz_localize(tz)
  385. result = Timestamp(dt, tz=tz) + offset_s
  386. self.assertTrue(isinstance(result, Timestamp))
  387. self.assertEqual(result, expected_localize)
  388. def test_pickle_v0_15_2(self):
  389. offsets = {'DateOffset': DateOffset(years=1),
  390. 'MonthBegin': MonthBegin(1),
  391. 'Day': Day(1),
  392. 'YearBegin': YearBegin(1),
  393. 'Week': Week(1)}
  394. pickle_path = os.path.join(tm.get_data_path(),
  395. 'dateoffset_0_15_2.pickle')
  396. # This code was executed once on v0.15.2 to generate the pickle:
  397. # with open(pickle_path, 'wb') as f: pickle.dump(offsets, f)
  398. #
  399. tm.assert_dict_equal(offsets, read_pickle(pickle_path))
  400. class TestDateOffset(Base):
  401. _multiprocess_can_split_ = True
  402. def setUp(self):
  403. self.d = Timestamp(datetime(2008, 1, 2))
  404. _offset_map.clear()
  405. def test_repr(self):
  406. repr(DateOffset())
  407. repr(DateOffset(2))
  408. repr(2 * DateOffset())
  409. repr(2 * DateOffset(months=2))
  410. def test_mul(self):
  411. assert DateOffset(2) == 2 * DateOffset(1)
  412. assert DateOffset(2) == DateOffset(1) * 2
  413. def test_constructor(self):
  414. assert ((self.d + DateOffset(months=2)) == datetime(2008, 3, 2))
  415. assert ((self.d - DateOffset(months=2)) == datetime(2007, 11, 2))
  416. assert ((self.d + DateOffset(2)) == datetime(2008, 1, 4))
  417. assert not DateOffset(2).isAnchored()
  418. assert DateOffset(1).isAnchored()
  419. d = datetime(2008, 1, 31)
  420. assert ((d + DateOffset(months=1)) == datetime(2008, 2, 29))
  421. def test_copy(self):
  422. assert (DateOffset(months=2).copy() == DateOffset(months=2))
  423. def test_eq(self):
  424. offset1 = DateOffset(days=1)
  425. offset2 = DateOffset(days=365)
  426. self.assertNotEqual(offset1, offset2)
  427. class TestBusinessDay(Base):
  428. _multiprocess_can_split_ = True
  429. _offset = BDay
  430. def setUp(self):
  431. self.d = datetime(2008, 1, 1)
  432. self.offset = BDay()
  433. self.offset2 = BDay(2)
  434. def test_different_normalize_equals(self):
  435. # equivalent in this special case
  436. offset = BDay()
  437. offset2 = BDay()
  438. offset2.normalize = True
  439. self.assertEqual(offset, offset2)
  440. def test_repr(self):
  441. self.assertEqual(repr(self.offset), '<BusinessDay>')
  442. assert repr(self.offset2) == '<2 * BusinessDays>'
  443. expected = '<BusinessDay: offset=datetime.timedelta(1)>'
  444. assert repr(self.offset + timedelta(1)) == expected
  445. def test_with_offset(self):
  446. offset = self.offset + timedelta(hours=2)
  447. assert (self.d + offset) == datetime(2008, 1, 2, 2)
  448. def testEQ(self):
  449. self.assertEqual(self.offset2, self.offset2)
  450. def test_mul(self):
  451. pass
  452. def test_hash(self):
  453. self.assertEqual(hash(self.offset2), hash(self.offset2))
  454. def testCall(self):
  455. self.assertEqual(self.offset2(self.d), datetime(2008, 1, 3))
  456. def testRAdd(self):
  457. self.assertEqual(self.d + self.offset2, self.offset2 + self.d)
  458. def testSub(self):
  459. off = self.offset2
  460. self.assertRaises(Exception, off.__sub__, self.d)
  461. self.assertEqual(2 * off - off, off)
  462. self.assertEqual(self.d - self.offset2, self.d + BDay(-2))
  463. def testRSub(self):
  464. self.assertEqual(self.d - self.offset2, (-self.offset2).apply(self.d))
  465. def testMult1(self):
  466. self.assertEqual(self.d + 10 * self.offset, self.d + BDay(10))
  467. def testMult2(self):
  468. self.assertEqual(self.d + (-5 * BDay(-10)), self.d + BDay(50))
  469. def testRollback1(self):
  470. self.assertEqual(BDay(10).rollback(self.d), self.d)
  471. def testRollback2(self):
  472. self.assertEqual(
  473. BDay(10).rollback(datetime(2008, 1, 5)), datetime(2008, 1, 4))
  474. def testRollforward1(self):
  475. self.assertEqual(BDay(10).rollforward(self.d), self.d)
  476. def testRollforward2(self):
  477. self.assertEqual(
  478. BDay(10).rollforward(datetime(2008, 1, 5)), datetime(2008, 1, 7))
  479. def test_roll_date_object(self):
  480. offset = BDay()
  481. dt = date(2012, 9, 15)
  482. result = offset.rollback(dt)
  483. self.assertEqual(result, datetime(2012, 9, 14))
  484. result = offset.rollforward(dt)
  485. self.assertEqual(result, datetime(2012, 9, 17))
  486. offset = offsets.Day()
  487. result = offset.rollback(dt)
  488. self.assertEqual(result, datetime(2012, 9, 15))
  489. result = offset.rollforward(dt)
  490. self.assertEqual(result, datetime(2012, 9, 15))
  491. def test_onOffset(self):
  492. tests = [(BDay(), datetime(2008, 1, 1), True),
  493. (BDay(), datetime(2008, 1, 5), False)]
  494. for offset, d, expected in tests:
  495. assertOnOffset(offset, d, expected)
  496. def test_apply(self):
  497. tests = []
  498. tests.append((bday, {datetime(2008, 1, 1): datetime(2008, 1, 2),
  499. datetime(2008, 1, 4): datetime(2008, 1, 7),
  500. datetime(2008, 1, 5): datetime(2008, 1, 7),
  501. datetime(2008, 1, 6): datetime(2008, 1, 7),
  502. datetime(2008, 1, 7): datetime(2008, 1, 8)}))
  503. tests.append((2 * bday, {datetime(2008, 1, 1): datetime(2008, 1, 3),
  504. datetime(2008, 1, 4): datetime(2008, 1, 8),
  505. datetime(2008, 1, 5): datetime(2008, 1, 8),
  506. datetime(2008, 1, 6): datetime(2008, 1, 8),
  507. datetime(2008, 1, 7): datetime(2008, 1, 9)}))
  508. tests.append((-bday, {datetime(2008, 1, 1): datetime(2007, 12, 31),
  509. datetime(2008, 1, 4): datetime(2008, 1, 3),
  510. datetime(2008, 1, 5): datetime(2008, 1, 4),
  511. datetime(2008, 1, 6): datetime(2008, 1, 4),
  512. datetime(2008, 1, 7): datetime(2008, 1, 4),
  513. datetime(2008, 1, 8): datetime(2008, 1, 7)}))
  514. tests.append((-2 * bday, {datetime(2008, 1, 1): datetime(2007, 12, 28),
  515. datetime(2008, 1, 4): datetime(2008, 1, 2),
  516. datetime(2008, 1, 5): datetime(2008, 1, 3),
  517. datetime(2008, 1, 6): datetime(2008, 1, 3),
  518. datetime(2008, 1, 7): datetime(2008, 1, 3),
  519. datetime(2008, 1, 8): datetime(2008, 1, 4),
  520. datetime(2008, 1, 9): datetime(2008, 1, 7)}))
  521. tests.append((BDay(0), {datetime(2008, 1, 1): datetime(2008, 1, 1),
  522. datetime(2008, 1, 4): datetime(2008, 1, 4),
  523. datetime(2008, 1, 5): datetime(2008, 1, 7),
  524. datetime(2008, 1, 6): datetime(2008, 1, 7),
  525. datetime(2008, 1, 7): datetime(2008, 1, 7)}))
  526. for offset, cases in tests:
  527. for base, expected in compat.iteritems(cases):
  528. assertEq(offset, base, expected)
  529. def test_apply_large_n(self):
  530. dt = datetime(2012, 10, 23)
  531. result = dt + BDay(10)
  532. self.assertEqual(result, datetime(2012, 11, 6))
  533. result = dt + BDay(100) - BDay(100)
  534. self.assertEqual(result, dt)
  535. off = BDay() * 6
  536. rs = datetime(2012, 1, 1) - off
  537. xp = datetime(2011, 12, 23)
  538. self.assertEqual(rs, xp)
  539. st = datetime(2011, 12, 18)
  540. rs = st + off
  541. xp = datetime(2011, 12, 26)
  542. self.assertEqual(rs, xp)
  543. off = BDay() * 10
  544. rs = datetime(2014, 1, 5) + off # see #5890
  545. xp = datetime(2014, 1, 17)
  546. self.assertEqual(rs, xp)
  547. def test_apply_corner(self):
  548. self.assertRaises(TypeError, BDay().apply, BMonthEnd())
  549. def test_offsets_compare_equal(self):
  550. # root cause of #456
  551. offset1 = BDay()
  552. offset2 = BDay()
  553. self.assertFalse(offset1 != offset2)
  554. class TestBusinessHour(Base):
  555. _multiprocess_can_split_ = True
  556. _offset = BusinessHour
  557. def setUp(self):
  558. self.d = datetime(2014, 7, 1, 10, 00)
  559. self.offset1 = BusinessHour()
  560. self.offset2 = BusinessHour(n=3)
  561. self.offset3 = BusinessHour(n=-1)
  562. self.offset4 = BusinessHour(n=-4)
  563. from datetime import time as dt_time
  564. self.offset5 = BusinessHour(start=dt_time(11, 0), end=dt_time(14, 30))
  565. self.offset6 = BusinessHour(start='20:00', end='05:00')
  566. self.offset7 = BusinessHour(n=-2, start=dt_time(21, 30),
  567. end=dt_time(6, 30))
  568. def test_constructor_errors(self):
  569. from datetime import time as dt_time
  570. with tm.assertRaises(ValueError):
  571. BusinessHour(start=dt_time(11, 0, 5))
  572. with tm.assertRaises(ValueError):
  573. BusinessHour(start='AAA')
  574. with tm.assertRaises(ValueError):
  575. BusinessHour(start='14:00:05')
  576. def test_different_normalize_equals(self):
  577. # equivalent in this special case
  578. offset = self._offset()
  579. offset2 = self._offset()
  580. offset2.normalize = True
  581. self.assertEqual(offset, offset2)
  582. def test_repr(self):
  583. self.assertEqual(repr(self.offset1), '<BusinessHour: BH=09:00-17:00>')
  584. self.assertEqual(repr(self.offset2),
  585. '<3 * BusinessHours: BH=09:00-17:00>')
  586. self.assertEqual(repr(self.offset3),
  587. '<-1 * BusinessHour: BH=09:00-17:00>')
  588. self.assertEqual(repr(self.offset4),
  589. '<-4 * BusinessHours: BH=09:00-17:00>')
  590. self.assertEqual(repr(self.offset5), '<BusinessHour: BH=11:00-14:30>')
  591. self.assertEqual(repr(self.offset6), '<BusinessHour: BH=20:00-05:00>')
  592. self.assertEqual(repr(self.offset7),
  593. '<-2 * BusinessHours: BH=21:30-06:30>')
  594. def test_with_offset(self):
  595. expected = Timestamp('2014-07-01 13:00')
  596. self.assertEqual(self.d + BusinessHour() * 3, expected)
  597. self.assertEqual(self.d + BusinessHour(n=3), expected)
  598. def testEQ(self):
  599. for offset in [self.offset1, self.offset2, self.offset3, self.offset4]:
  600. self.assertEqual(offset, offset)
  601. self.assertNotEqual(BusinessHour(), BusinessHour(-1))
  602. self.assertEqual(BusinessHour(start='09:00'), BusinessHour())
  603. self.assertNotEqual(BusinessHour(start='09:00'),
  604. BusinessHour(start='09:01'))
  605. self.assertNotEqual(BusinessHour(start='09:00', end='17:00'),
  606. BusinessHour(start='17:00', end='09:01'))
  607. def test_hash(self):
  608. for offset in [self.offset1, self.offset2, self.offset3, self.offset4]:
  609. self.assertEqual(hash(offset), hash(offset))
  610. def testCall(self):
  611. self.assertEqual(self.offset1(self.d), datetime(2014, 7, 1, 11))
  612. self.assertEqual(self.offset2(self.d), datetime(2014, 7, 1, 13))
  613. self.assertEqual(self.offset3(self.d), datetime(2014, 6, 30, 17))
  614. self.assertEqual(self.offset4(self.d), datetime(2014, 6, 30, 14))
  615. def testRAdd(self):
  616. self.assertEqual(self.d + self.offset2, self.offset2 + self.d)
  617. def testSub(self):
  618. off = self.offset2
  619. self.assertRaises(Exception, off.__sub__, self.d)
  620. self.assertEqual(2 * off - off, off)
  621. self.assertEqual(self.d - self.offset2, self.d + self._offset(-3))
  622. def testRSub(self):
  623. self.assertEqual(self.d - self.offset2, (-self.offset2).apply(self.d))
  624. def testMult1(self):
  625. self.assertEqual(self.d + 5 * self.offset1, self.d + self._offset(5))
  626. def testMult2(self):
  627. self.assertEqual(self.d + (-3 * self._offset(-2)),
  628. self.d + self._offset(6))
  629. def testRollback1(self):
  630. self.assertEqual(self.offset1.rollback(self.d), self.d)
  631. self.assertEqual(self.offset2.rollback(self.d), self.d)
  632. self.assertEqual(self.offset3.rollback(self.d), self.d)
  633. self.assertEqual(self.offset4.rollback(self.d), self.d)
  634. self.assertEqual(self.offset5.rollback(self.d),
  635. datetime(2014, 6, 30, 14, 30))
  636. self.assertEqual(self.offset6.rollback(
  637. self.d), datetime(2014, 7, 1, 5, 0))
  638. self.assertEqual(self.offset7.rollback(
  639. self.d), datetime(2014, 7, 1, 6, 30))
  640. d = datetime(2014, 7, 1, 0)
  641. self.assertEqual(self.offset1.rollback(d), datetime(2014, 6, 30, 17))
  642. self.assertEqual(self.offset2.rollback(d), datetime(2014, 6, 30, 17))
  643. self.assertEqual(self.offset3.rollback(d), datetime(2014, 6, 30, 17))
  644. self.assertEqual(self.offset4.rollback(d), datetime(2014, 6, 30, 17))
  645. self.assertEqual(self.offset5.rollback(
  646. d), datetime(2014, 6, 30, 14, 30))
  647. self.assertEqual(self.offset6.rollback(d), d)
  648. self.assertEqual(self.offset7.rollback(d), d)
  649. self.assertEqual(self._offset(5).rollback(self.d), self.d)
  650. def testRollback2(self):
  651. self.assertEqual(self._offset(-3)
  652. .rollback(datetime(2014, 7, 5, 15, 0)),
  653. datetime(2014, 7, 4, 17, 0))
  654. def testRollforward1(self):
  655. self.assertEqual(self.offset1.rollforward(self.d), self.d)
  656. self.assertEqual(self.offset2.rollforward(self.d), self.d)
  657. self.assertEqual(self.offset3.rollforward(self.d), self.d)
  658. self.assertEqual(self.offset4.rollforward(self.d), self.d)
  659. self.assertEqual(self.offset5.rollforward(
  660. self.d), datetime(2014, 7, 1, 11, 0))
  661. self.assertEqual(self.offset6.rollforward(
  662. self.d), datetime(2014, 7, 1, 20, 0))
  663. self.assertEqual(self.offset7.rollforward(
  664. self.d), datetime(2014, 7, 1, 21, 30))
  665. d = datetime(2014, 7, 1, 0)
  666. self.assertEqual(self.offset1.rollforward(d), datetime(2014, 7, 1, 9))
  667. self.assertEqual(self.offset2.rollforward(d), datetime(2014, 7, 1, 9))
  668. self.assertEqual(self.offset3.rollforward(d), datetime(2014, 7, 1, 9))
  669. self.assertEqual(self.offset4.rollforward(d), datetime(2014, 7, 1, 9))
  670. self.assertEqual(self.offset5.rollforward(d), datetime(2014, 7, 1, 11))
  671. self.assertEqual(self.offset6.rollforward(d), d)
  672. self.assertEqual(self.offset7.rollforward(d), d)
  673. self.assertEqual(self._offset(5).rollforward(self.d), self.d)
  674. def testRollforward2(self):
  675. self.assertEqual(self._offset(-3)
  676. .rollforward(datetime(2014, 7, 5, 16, 0)),
  677. datetime(2014, 7, 7, 9))
  678. def test_roll_date_object(self):
  679. offset = BusinessHour()
  680. dt = datetime(2014, 7, 6, 15, 0)
  681. result = offset.rollback(dt)
  682. self.assertEqual(result, datetime(2014, 7, 4, 17))
  683. result = offset.rollforward(dt)
  684. self.assertEqual(result, datetime(2014, 7, 7, 9))
  685. def test_normalize(self):
  686. tests = []
  687. tests.append((BusinessHour(normalize=True),
  688. {datetime(2014, 7, 1, 8): datetime(2014, 7, 1),
  689. datetime(2014, 7, 1, 17): datetime(2014, 7, 2),
  690. datetime(2014, 7, 1, 16): datetime(2014, 7, 2),
  691. datetime(2014, 7, 1, 23): datetime(2014, 7, 2),
  692. datetime(2014, 7, 1, 0): datetime(2014, 7, 1),
  693. datetime(2014, 7, 4, 15): datetime(2014, 7, 4),
  694. datetime(2014, 7, 4, 15, 59): datetime(2014, 7, 4),
  695. datetime(2014, 7, 4, 16, 30): datetime(2014, 7, 7),
  696. datetime(2014, 7, 5, 23): datetime(2014, 7, 7),
  697. datetime(2014, 7, 6, 10): datetime(2014, 7, 7)}))
  698. tests.append((BusinessHour(-1, normalize=True),
  699. {datetime(2014, 7, 1, 8): datetime(2014, 6, 30),
  700. datetime(2014, 7, 1, 17): datetime(2014, 7, 1),
  701. datetime(2014, 7, 1, 16): datetime(2014, 7, 1),
  702. datetime(2014, 7, 1, 10): datetime(2014, 6, 30),
  703. datetime(2014, 7, 1, 0): datetime(2014, 6, 30),
  704. datetime(2014, 7, 7, 10): datetime(2014, 7, 4),
  705. datetime(2014, 7, 7, 10, 1): datetime(2014, 7, 7),
  706. datetime(2014, 7, 5, 23): datetime(2014, 7, 4),
  707. datetime(2014, 7, 6, 10): datetime(2014, 7, 4)}))
  708. tests.append((BusinessHour(1, normalize=True, start='17:00',
  709. end='04:00'),
  710. {datetime(2014, 7, 1, 8): datetime(2014, 7, 1),
  711. datetime(2014, 7, 1, 17): datetime(2014, 7, 1),
  712. datetime(2014, 7, 1, 23): datetime(2014, 7, 2),
  713. datetime(2014, 7, 2, 2): datetime(2014, 7, 2),
  714. datetime(2014, 7, 2, 3): datetime(2014, 7, 2),
  715. datetime(2014, 7, 4, 23): datetime(2014, 7, 5),
  716. datetime(2014, 7, 5, 2): datetime(2014, 7, 5),
  717. datetime(2014, 7, 7, 2): datetime(2014, 7, 7),
  718. datetime(2014, 7, 7, 17): datetime(2014, 7, 7)}))
  719. for offset, cases in tests:
  720. for dt, expected in compat.iteritems(cases):
  721. self.assertEqual(offset.apply(dt), expected)
  722. def test_onOffset(self):
  723. tests = []
  724. tests.append((BusinessHour(), {datetime(2014, 7, 1, 9): True,
  725. datetime(2014, 7, 1, 8, 59): False,
  726. datetime(2014, 7, 1, 8): False,
  727. datetime(2014, 7, 1, 17): True,
  728. datetime(2014, 7, 1, 17, 1): False,
  729. datetime(2014, 7, 1, 18): False,
  730. datetime(2014, 7, 5, 9): False,
  731. datetime(2014, 7, 6, 12): False}))
  732. tests.append((BusinessHour(start='10:00', end='15:00'),
  733. {datetime(2014, 7, 1, 9): False,
  734. datetime(2014, 7, 1, 10): True,
  735. datetime(2014, 7, 1, 15): True,
  736. datetime(2014, 7, 1, 15, 1): False,
  737. datetime(2014, 7, 5, 12): False,
  738. datetime(2014, 7, 6, 12): False}))
  739. tests.append((BusinessHour(start='19:00', end='05:00'),
  740. {datetime(2014, 7, 1, 9, 0): False,
  741. datetime(2014, 7, 1, 10, 0): False,
  742. datetime(2014, 7, 1, 15): False,
  743. datetime(2014, 7, 1, 15, 1): False,
  744. datetime(2014, 7, 5, 12, 0): False,
  745. datetime(2014, 7, 6, 12, 0): False,
  746. datetime(2014, 7, 1, 19, 0): True,
  747. datetime(2014, 7, 2, 0, 0): True,
  748. datetime(2014, 7, 4, 23): True,
  749. datetime(2014, 7, 5, 1): True,
  750. datetime(2014, 7, 5, 5, 0): True,
  751. datetime(2014, 7, 6, 23, 0): False,
  752. datetime(2014, 7, 7, 3, 0): False}))
  753. for offset, cases in tests:
  754. for dt, expected in compat.iteritems(cases):
  755. self.assertEqual(offset.onOffset(dt), expected)
  756. def test_opening_time(self):
  757. tests = []
  758. # opening time should be affected by sign of n, not by n's value and
  759. # end
  760. tests.append((
  761. [BusinessHour(), BusinessHour(n=2), BusinessHour(
  762. n=4), BusinessHour(end='10:00'), BusinessHour(n=2, end='4:00'),
  763. BusinessHour(n=4, end='15:00')],
  764. {datetime(2014, 7, 1, 11): (datetime(2014, 7, 2, 9), datetime(
  765. 2014, 7, 1, 9)),
  766. datetime(2014, 7, 1, 18): (datetime(2014, 7, 2, 9), datetime(
  767. 2014, 7, 1, 9)),
  768. datetime(2014, 7, 1, 23): (datetime(2014, 7, 2, 9), datetime(
  769. 2014, 7, 1, 9)),
  770. datetime(2014, 7, 2, 8): (datetime(2014, 7, 2, 9), datetime(
  771. 2014, 7, 1, 9)),
  772. # if timestamp is on opening time, next opening time is
  773. # as it is
  774. datetime(2014, 7, 2, 9): (datetime(2014, 7, 2, 9), datetime(
  775. 2014, 7, 2, 9)),
  776. datetime(2014, 7, 2, 10): (datetime(2014, 7, 3, 9), datetime(
  777. 2014, 7, 2, 9)),
  778. # 2014-07-05 is saturday
  779. datetime(2014, 7, 5, 10): (datetime(2014, 7, 7, 9), datetime(
  780. 2014, 7, 4, 9)),
  781. datetime(2014, 7, 4, 10): (datetime(2014, 7, 7, 9), datetime(
  782. 2014, 7, 4, 9)),
  783. datetime(2014, 7, 4, 23): (datetime(2014, 7, 7, 9), datetime(
  784. 2014, 7, 4, 9)),
  785. datetime(2014, 7, 6, 10): (datetime(2014, 7, 7, 9), datetime(
  786. 2014, 7, 4, 9)),
  787. datetime(2014, 7, 7, 5): (datetime(2014, 7, 7, 9), datetime(
  788. 2014, 7, 4, 9)),
  789. datetime(2014, 7, 7, 9, 1): (datetime(2014, 7, 8, 9), datetime(
  790. 2014, 7, 7, 9))}))
  791. tests.append(([BusinessHour(start='11:15'),
  792. BusinessHour(n=2, start='11:15'),
  793. BusinessHour(n=3, start='11:15'),
  794. BusinessHour(start='11:15', end='10:00'),
  795. BusinessHour(n=2, start='11:15', end='4:00'),
  796. BusinessHour(n=3, start='11:15', end='15:00')],
  797. {datetime(2014, 7, 1, 11): (datetime(
  798. 2014, 7, 1, 11, 15), datetime(2014, 6, 30, 11, 15)),
  799. datetime(2014, 7, 1, 18): (datetime(
  800. 2014, 7, 2, 11, 15), datetime(2014, 7, 1, 11, 15)),
  801. datetime(2014, 7, 1, 23): (datetime(
  802. 2014, 7, 2, 11, 15), datetime(2014, 7, 1, 11, 15)),
  803. datetime(2014, 7, 2, 8): (datetime(2014, 7, 2, 11, 15),
  804. datetime(2014, 7, 1, 11, 15)),
  805. datetime(2014, 7, 2, 9): (datetime(2014, 7, 2, 11, 15),
  806. datetime(2014, 7, 1, 11, 15)),
  807. datetime(2014, 7, 2, 10): (datetime(
  808. 2014, 7, 2, 11, 15), datetime(2014, 7, 1, 11, 15)),
  809. datetime(2014, 7, 2, 11, 15): (datetime(
  810. 2014, 7, 2, 11, 15), datetime(2014, 7, 2, 11, 15)),
  811. datetime(2014, 7, 2, 11, 15, 1): (datetime(
  812. 2014, 7, 3, 11, 15), datetime(2014, 7, 2, 11, 15)),
  813. datetime(2014, 7, 5, 10): (datetime(
  814. 2014, 7, 7, 11, 15), datetime(2014, 7, 4, 11, 15)),
  815. datetime(2014, 7, 4, 10): (datetime(
  816. 2014, 7, 4, 11, 15), datetime(2014, 7, 3, 11, 15)),
  817. datetime(2014, 7, 4, 23): (datetime(
  818. 2014, 7, 7, 11, 15), datetime(2014, 7, 4, 11, 15)),
  819. datetime(2014, 7, 6, 10): (datetime(
  820. 2014, 7, 7, 11, 15), datetime(2014, 7, 4, 11, 15)),
  821. datetime(2014, 7, 7, 5): (datetime(2014, 7, 7, 11, 15),
  822. datetime(2014, 7, 4, 11, 15)),
  823. datetime(2014, 7, 7, 9, 1): (
  824. datetime(2014, 7, 7, 11, 15),
  825. datetime(2014, 7, 4, 11, 15))}))
  826. tests.append(([BusinessHour(-1), BusinessHour(n=-2),
  827. BusinessHour(n=-4),
  828. BusinessHour(n=-1, end='10:00'),
  829. BusinessHour(n=-2, end='4:00'),
  830. BusinessHour(n=-4, end='15:00')],
  831. {datetime(2014, 7, 1, 11): (datetime(2014, 7, 1, 9),
  832. datetime(2014, 7, 2, 9)),
  833. datetime(2014, 7, 1, 18): (datetime(2014, 7, 1, 9),
  834. datetime(2014, 7, 2, 9)),
  835. datetime(2014, 7, 1, 23): (datetime(2014, 7, 1, 9),
  836. datetime(2014, 7, 2, 9)),
  837. datetime(2014, 7, 2, 8): (datetime(2014, 7, 1, 9),
  838. datetime(2014, 7, 2, 9)),
  839. datetime(2014, 7, 2, 9): (datetime(2014, 7, 2, 9),
  840. datetime(2014, 7, 2, 9)),
  841. datetime(2014, 7, 2, 10): (datetime(2014, 7, 2, 9),
  842. datetime(2014, 7, 3, 9)),
  843. datetime(2014, 7, 5, 10): (datetime(2014, 7, 4, 9),
  844. datetime(2014, 7, 7, 9)),
  845. datetime(2014, 7, 4, 10): (datetime(2014, 7, 4, 9),
  846. datetime(2014, 7, 7, 9)),
  847. datetime(2014, 7, 4, 23): (datetime(2014, 7, 4, 9),
  848. datetime(2014, 7, 7, 9)),
  849. datetime(2014, 7, 6, 10): (datetime(2014, 7, 4, 9),
  850. datetime(2014, 7, 7, 9)),
  851. datetime(2014, 7, 7, 5): (datetime(2014, 7, 4, 9),
  852. datetime(2014, 7, 7, 9)),
  853. datetime(2014, 7, 7, 9): (datetime(2014, 7, 7, 9),
  854. datetime(2014, 7, 7, 9)),
  855. datetime(2014, 7, 7, 9, 1): (datetime(2014, 7, 7, 9),
  856. datetime(2014, 7, 8, 9))}))
  857. tests.append(([BusinessHour(start='17:00', end='05:00'),
  858. BusinessHour(n=3, start='17:00', end='03:00')],
  859. {datetime(2014, 7, 1, 11): (datetime(2014, 7, 1, 17),
  860. datetime(2014, 6, 30, 17)),
  861. datetime(2014, 7, 1, 18): (datetime(2014, 7, 2, 17),
  862. datetime(2014, 7, 1, 17)),
  863. datetime(2014, 7, 1, 23): (datetime(2014, 7, 2, 17),
  864. datetime(2014, 7, 1, 17)),
  865. datetime(2014, 7, 2, 8): (datetime(2014, 7, 2, 17),
  866. datetime(2014, 7, 1, 17)),
  867. datetime(2014, 7, 2, 9): (datetime(2014, 7, 2, 17),
  868. datetime(2014, 7, 1, 17)),
  869. datetime(2014, 7, 4, 17): (datetime(2014, 7, 4, 17),
  870. datetime(2014, 7, 4, 17)),
  871. datetime(2014, 7, 5, 10): (datetime(2014, 7, 7, 17),
  872. datetime(2014, 7, 4, 17)),
  873. datetime(2014, 7, 4, 10): (datetime(2014, 7, 4, 17),
  874. datetime(2014, 7, 3, 17)),
  875. datetime(2014, 7, 4, 23): (datetime(2014, 7, 7, 17),
  876. datetime(2014, 7, 4, 17)),
  877. datetime(2014, 7, 6, 10): (datetime(2014, 7, 7, 17),
  878. datetime(2014, 7, 4, 17)),
  879. datetime(2014, 7, 7, 5): (datetime(2014, 7, 7, 17),
  880. datetime(2014, 7, 4, 17)),
  881. datetime(2014, 7, 7, 17, 1): (datetime(
  882. 2014, 7, 8, 17), datetime(2014, 7, 7, 17)), }))
  883. tests.append(([BusinessHour(-1, start='17:00', end='05:00'),
  884. BusinessHour(n=-2, start='17:00', end='03:00')],
  885. {datetime(2014, 7, 1, 11): (datetime(2014, 6, 30, 17),
  886. datetime(2014, 7, 1, 17)),
  887. datetime(2014, 7, 1, 18): (datetime(2014, 7, 1, 17),
  888. datetime(2014, 7, 2, 17)),
  889. datetime(2014, 7, 1, 23): (datetime(2014, 7, 1, 17),
  890. datetime(2014, 7, 2, 17)),
  891. datetime(2014, 7, 2, 8): (datetime(2014, 7, 1, 17),
  892. datetime(2014, 7, 2, 17)),
  893. datetime(2014, 7, 2, 9): (datetime(2014, 7, 1, 17),
  894. datetime(2014, 7, 2, 17)),
  895. datetime(2014, 7, 2, 16, 59): (datetime(
  896. 2014, 7, 1, 17), datetime(2014, 7, 2, 17)),
  897. datetime(2014, 7, 5, 10): (datetime(2014, 7, 4, 17),
  898. datetime(2014, 7, 7, 17)),
  899. datetime(2014, 7, 4, 10): (datetime(2014, 7, 3, 17),
  900. datetime(2014, 7, 4, 17)),
  901. datetime(2014, 7, 4, 23): (datetime(2014, 7, 4, 17),
  902. datetime(2014, 7, 7, 17)),
  903. datetime(2014, 7, 6, 10): (datetime(2014, 7, 4, 17),
  904. datetime(2014, 7, 7, 17)),
  905. datetime(2014, 7, 7, 5): (datetime(2014, 7, 4, 17),
  906. datetime(2014, 7, 7, 17)),
  907. datetime(2014, 7, 7, 18): (datetime(2014, 7, 7, 17),
  908. datetime(2014, 7, 8, 17))}))
  909. for _offsets, cases in tests:
  910. for offset in _offsets:
  911. for dt, (exp_next, exp_prev) in compat.iteritems(cases):
  912. self.assertEqual(offset._next_opening_time(dt), exp_next)
  913. self.assertEqual(offset._prev_opening_time(dt), exp_prev)
  914. def test_apply(self):
  915. tests = []
  916. tests.append((
  917. BusinessHour(),
  918. {datetime(2014, 7, 1, 11): datetime(2014, 7, 1, 12),
  919. datetime(2014, 7, 1, 13): datetime(2014, 7, 1, 14),
  920. datetime(2014, 7, 1, 15): datetime(2014, 7, 1, 16),
  921. datetime(2014, 7, 1, 19): datetime(2014, 7, 2, 10),
  922. datetime(2014, 7, 1, 16): datetime(2014, 7, 2, 9),
  923. datetime(2014, 7, 1, 16, 30, 15): datetime(2014, 7, 2, 9, 30, 15),
  924. datetime(2014, 7, 1, 17): datetime(2014, 7, 2, 10),
  925. datetime(2014, 7, 2, 11): datetime(2014, 7, 2, 12),
  926. # out of business hours
  927. datetime(2014, 7, 2, 8): datetime(2014, 7, 2, 10),
  928. datetime(2014, 7, 2, 19): datetime(2014, 7, 3, 10),
  929. datetime(2014, 7, 2, 23): datetime(2014, 7, 3, 10),
  930. datetime(2014, 7, 3, 0): datetime(2014, 7, 3, 10),
  931. # saturday
  932. datetime(2014, 7, 5, 15): datetime(2014, 7, 7, 10),
  933. datetime(2014, 7, 4, 17): datetime(2014, 7, 7, 10),
  934. datetime(2014, 7, 4, 16, 30): datetime(2014, 7, 7, 9, 30),
  935. datetime(2014, 7, 4, 16, 30, 30): datetime(2014, 7, 7, 9, 30,
  936. 30)}))
  937. tests.append((BusinessHour(
  938. 4), {datetime(2014, 7, 1, 11): datetime(2014, 7, 1, 15),
  939. datetime(2014, 7, 1, 13): datetime(2014, 7, 2, 9),
  940. datetime(2014, 7, 1, 15): datetime(2014, 7, 2, 11),
  941. datetime(2014, 7, 1, 16): datetime(2014, 7, 2, 12),
  942. datetime(2014, 7, 1, 17): datetime(2014, 7, 2, 13),
  943. datetime(2014, 7, 2, 11): datetime(2014, 7, 2, 15),
  944. datetime(2014, 7, 2, 8): datetime(2014, 7, 2, 13),
  945. datetime(2014, 7, 2, 19): datetime(2014, 7, 3, 13),
  946. datetime(2014, 7, 2, 23): datetime(2014, 7, 3, 13),
  947. datetime(2014, 7, 3, 0): datetime(2014, 7, 3, 13),
  948. datetime(2014, 7, 5, 15): datetime(2014, 7, 7, 13),
  949. datetime(2014, 7, 4, 17): datetime(2014, 7, 7, 13),
  950. datetime(2014, 7, 4, 16, 30): datetime(2014, 7, 7, 12, 30),
  951. datetime(2014, 7, 4, 16, 30, 30): datetime(2014, 7, 7, 12, 30,
  952. 30)}))
  953. tests.append(
  954. (BusinessHour(-1),
  955. {datetime(2014, 7, 1, 11): datetime(2014, 7, 1, 10),
  956. datetime(2014, 7, 1, 13): datetime(2014, 7, 1, 12),
  957. datetime(2014, 7, 1, 15): datetime(2014, 7, 1, 14),
  958. datetime(2014, 7, 1, 16): datetime(2014, 7, 1, 15),
  959. datetime(2014, 7, 1, 10): datetime(2014, 6, 30, 17),
  960. datetime(2014, 7, 1, 16, 30, 15): datetime(
  961. 2014, 7, 1, 15, 30, 15),
  962. datetime(2014, 7, 1, 9, 30, 15): datetime(
  963. 2014, 6, 30, 16, 30, 15),
  964. datetime(2014, 7, 1, 17): datetime(2014, 7, 1, 16),
  965. datetime(2014, 7, 1, 5): datetime(2014, 6, 30, 16),
  966. datetime(2014, 7, 2, 11): datetime(2014, 7, 2, 10),
  967. # out of business hours
  968. datetime(2014, 7, 2, 8): datetime(2014, 7, 1, 16),
  969. datetime(2014, 7, 2, 19): datetime(2014, 7, 2, 16),
  970. datetime(2014, 7, 2, 23): datetime(2014, 7, 2, 16),
  971. datetime(2014, 7, 3, 0): datetime(2014, 7, 2, 16),
  972. # saturday
  973. datetime(2014, 7, 5, 15): datetime(2014, 7, 4, 16),
  974. datetime(2014, 7, 7, 9): datetime(2014, 7, 4, 16),
  975. datetime(2014, 7, 7, 9, 30): datetime(2014, 7, 4, 16, 30),
  976. datetime(2014, 7, 7, 9, 30, 30): datetime(2014, 7, 4, 16, 30,
  977. 30)}))
  978. tests.append((BusinessHour(
  979. -4), {datetime(2014, 7, 1, 11): datetime(2014, 6, 30, 15),
  980. datetime(2014, 7, 1, 13): datetime(2014, 6, 30, 17),
  981. datetime(2014, 7, 1, 15): datetime(2014, 7, 1, 11),
  982. datetime(2014, 7, 1, 16): datetime(2014, 7, 1, 12),
  983. datetime(2014, 7, 1, 17): datetime(2014, 7, 1, 13),
  984. datetime(2014, 7, 2, 11): datetime(2014, 7, 1, 15),
  985. datetime(2014, 7, 2, 8): datetime(2014, 7, 1, 13),
  986. datetime(2014, 7, 2, 19): datetime(2014, 7, 2, 13),
  987. datetime(2014, 7, 2, 23): datetime(2014, 7, 2, 13),
  988. datetime(2014, 7, 3, 0): datetime(2014, 7, 2, 13),
  989. datetime(2014, 7, 5, 15): datetime(2014, 7, 4, 13),
  990. datetime(2014, 7, 4, 18): datetime(2014, 7, 4, 13),
  991. datetime(2014, 7, 7, 9, 30): datetime(2014, 7, 4, 13, 30),
  992. datetime(2014, 7, 7, 9, 30, 30): datetime(2014, 7, 4, 13, 30,
  993. 30)}))
  994. tests.append((BusinessHour(start='13:00', end='16:00'),
  995. {datetime(2014, 7, 1, 11): datetime(2014, 7, 1, 14),
  996. datetime(2014, 7, 1, 13): datetime(2014, 7, 1, 14),
  997. datetime(2014, 7, 1, 15): datetime(2014, 7, 2, 13),
  998. datetime(2014, 7, 1, 19): datetime(2014, 7, 2, 14),
  999. datetime(2014, 7, 1, 16): datetime(2014, 7, 2, 14),
  1000. datetime(2014, 7, 1, 15, 30, 15): datetime(2014, 7, 2,
  1001. 13, 30, 15),
  1002. datetime(2014, 7, 5, 15): datetime(2014, 7, 7, 14),
  1003. datetime(2014, 7, 4, 17): datetime(2014, 7, 7, 14)}))
  1004. tests.append((BusinessHour(n=2, start='13:00', end='16:00'), {
  1005. datetime(2014, 7, 1, 17): datetime(2014, 7, 2, 15),
  1006. datetime(2014, 7, 2, 14): datetime(2014, 7, 3, 13),
  1007. datetime(2014, 7, 2, 8): datetime(2014, 7, 2, 15),
  1008. datetime(2014, 7, 2, 19): datetime(2014, 7, 3, 15),
  1009. datetime(2014, 7, 2, 14, 30): datetime(2014, 7, 3, 13, 30),
  1010. datetime(2014, 7, 3, 0): datetime(2014, 7, 3, 15),
  1011. datetime(2014, 7, 5, 15): datetime(2014, 7, 7, 15),
  1012. datetime(2014, 7, 4, 17): datetime(2014, 7, 7, 15),
  1013. datetime(2014, 7, 4, 14, 30): datetime(2014, 7, 7, 13, 30),
  1014. datetime(2014, 7, 4, 14, 30, 30): datetime(2014, 7, 7, 13, 30, 30)
  1015. }))
  1016. tests.append((BusinessHour(n=-1, start='13:00', end='16:00'),
  1017. {datetime(2014, 7, 2, 11): datetime(2014, 7, 1, 15),
  1018. datetime(2014, 7, 2, 13): datetime(2014, 7, 1, 15),
  1019. datetime(2014, 7, 2, 14): datetime(2014, 7, 1, 16),
  1020. datetime(2014, 7, 2, 15): datetime(2014, 7, 2, 14),
  1021. datetime(2014, 7, 2, 19): datetime(2014, 7, 2, 15),
  1022. datetime(2014, 7, 2, 16): datetime(2014, 7, 2, 15),
  1023. datetime(2014, 7, 2, 13, 30, 15): datetime(2014, 7, 1,
  1024. 15, 30, 15),
  1025. datetime(2014, 7, 5, 15): datetime(2014, 7, 4, 15),
  1026. datetime(2014, 7, 7, 11): datetime(2014, 7, 4, 15)}))
  1027. tests.append((BusinessHour(n=-3, start='10:00', end='16:00'), {
  1028. datetime(2014, 7, 1, 17): datetime(2014, 7, 1, 13),
  1029. datetime(2014, 7, 2, 14): datetime(2014, 7, 2, 11),
  1030. datetime(2014, 7, 2, 8): datetime(2014, 7, 1, 13),
  1031. datetime(2014, 7, 2, 13): datetime(2014, 7, 1, 16),
  1032. datetime(2014, 7, 2, 19): datetime(2014, 7, 2, 13),
  1033. datetime(2014, 7, 2, 11, 30): datetime(2014, 7, 1, 14, 30),
  1034. datetime(2014, 7, 3, 0): datetime(2014, 7, 2, 13),
  1035. datetime(2014, 7, 4, 10): datetime(2014, 7, 3, 13),
  1036. datetime(2014, 7, 5, 15): datetime(2014, 7, 4, 13),
  1037. datetime(2014, 7, 4, 16): datetime(2014, 7, 4, 13),
  1038. datetime(2014, 7, 4, 12, 30): datetime(2014, 7, 3, 15, 30),
  1039. datetime(2014, 7, 4, 12, 30, 30): datetime(2014, 7, 3, 15, 30, 30)
  1040. }))
  1041. tests.append((BusinessHour(start='19:00', end='05:00'), {
  1042. datetime(2014, 7, 1, 17): datetime(2014, 7, 1, 20),
  1043. datetime(2014, 7, 2, 14): datetime(2014, 7, 2, 20),
  1044. datetime(2014, 7, 2, 8): datetime(2014, 7, 2, 20),
  1045. datetime(2014, 7, 2, 13): datetime(2014, 7, 2, 20),
  1046. datetime(2014, 7, 2, 19): datetime(2014, 7, 2, 20),
  1047. datetime(2014, 7, 2, 4, 30): datetime(2014, 7, 2, 19, 30),
  1048. datetime(2014, 7, 3, 0): datetime(2014, 7, 3, 1),
  1049. datetime(2014, 7, 4, 10): datetime(2014, 7, 4, 20),
  1050. datetime(2014, 7, 4, 23): datetime(2014, 7, 5, 0),
  1051. datetime(2014, 7, 5, 0): datetime(2014, 7, 5, 1),
  1052. datetime(2014, 7, 5, 4): datetime(2014, 7, 7, 19),
  1053. datetime(2014, 7, 5, 4, 30): datetime(2014, 7, 7, 19, 30),
  1054. datetime(2014, 7, 5, 4, 30, 30): datetime(2014, 7, 7, 19, 30, 30)
  1055. }))
  1056. tests.append((BusinessHour(n=-1, start='19:00', end='05:00'), {
  1057. datetime(2014, 7, 1, 17): datetime(2014, 7, 1, 4),
  1058. datetime(2014, 7, 2, 14): datetime(2014, 7, 2, 4),
  1059. datetime(2014, 7, 2, 8): datetime(2014, 7, 2, 4),
  1060. datetime(2014, 7, 2, 13): datetime(2014, 7, 2, 4),
  1061. datetime(2014, 7, 2, 20): datetime(2014, 7, 2, 5),
  1062. datetime(2014, 7, 2, 19): datetime(2014, 7, 2, 4),
  1063. datetime(2014, 7, 2, 19, 30): datetime(2014, 7, 2, 4, 30),
  1064. datetime(2014, 7, 3, 0): datetime(2014, 7, 2, 23),
  1065. datetime(2014, 7, 3, 6): datetime(2014, 7, 3, 4),
  1066. datetime(2014, 7, 4, 23): datetime(2014, 7, 4, 22),
  1067. datetime(2014, 7, 5, 0): datetime(2014, 7, 4, 23),
  1068. datetime(2014, 7, 5, 4): datetime(2014, 7, 5, 3),
  1069. datetime(2014, 7, 7, 19, 30): datetime(2014, 7, 5, 4, 30),
  1070. datetime(2014, 7, 7, 19, 30, 30): datetime(2014, 7, 5, 4, 30, 30)
  1071. }))
  1072. for offset, cases in tests:
  1073. for base, expected in compat.iteritems(cases):
  1074. assertEq(offset, base, expected)
  1075. def test_apply_large_n(self):
  1076. tests = []
  1077. tests.append(
  1078. (BusinessHour(40), # A week later
  1079. {datetime(2014, 7, 1, 11): datetime(2014, 7, 8, 11),
  1080. datetime(2014, 7, 1, 13): datetime(2014, 7, 8, 13),
  1081. datetime(2014, 7, 1, 15): datetime(2014, 7, 8, 15),
  1082. datetime(2014, 7, 1, 16): datetime(2014, 7, 8, 16),
  1083. datetime(2014, 7, 1, 17): datetime(2014, 7, 9, 9),
  1084. datetime(2014, 7, 2, 11): datetime(2014, 7, 9, 11),
  1085. datetime(2014, 7, 2, 8): datetime(2014, 7, 9, 9),
  1086. datetime(2014, 7, 2, 19): datetime(2014, 7, 10, 9),
  1087. datetime(2014, 7, 2, 23): datetime(2014, 7, 10, 9),
  1088. datetime(2014, 7, 3, 0): datetime(2014, 7, 10, 9),
  1089. datetime(2014, 7, 5, 15): datetime(2014, 7, 14, 9),
  1090. datetime(2014, 7, 4, 18): datetime(2014, 7, 14, 9),
  1091. datetime(2014, 7, 7, 9, 30): datetime(2014, 7, 14, 9, 30),
  1092. datetime(2014, 7, 7, 9, 30, 30): datetime(2014, 7, 14, 9, 30,
  1093. 30)}))
  1094. tests.append(
  1095. (BusinessHour(-25), # 3 days and 1 hour before
  1096. {datetime(2014, 7, 1, 11): datetime(2014, 6, 26, 10),
  1097. datetime(2014, 7, 1, 13): datetime(2014, 6, 26, 12),
  1098. datetime(2014, 7, 1, 9): datetime(2014, 6, 25, 16),
  1099. datetime(2014, 7, 1, 10): datetime(2014, 6, 25, 17),
  1100. datetime(2014, 7, 3, 11): datetime(2014, 6, 30, 10),
  1101. datetime(2014, 7, 3, 8): datetime(2014, 6, 27, 16),
  1102. datetime(2014, 7, 3, 19): datetime(2014, 6, 30, 16),
  1103. datetime(2014, 7, 3, 23): datetime(2014, 6, 30, 16),
  1104. datetime(2014, 7, 4, 9): datetime(2014, 6, 30, 16),
  1105. datetime(2014, 7, 5, 15): datetime(2014, 7, 1, 16),
  1106. datetime(2014, 7, 6, 18): datetime(2014, 7, 1, 16),
  1107. datetime(2014, 7, 7, 9, 30): datetime(2014, 7, 1, 16, 30),
  1108. datetime(2014, 7, 7, 10, 30, 30): datetime(2014, 7, 2, 9, 30,
  1109. 30)}))
  1110. # 5 days and 3 hours later
  1111. tests.append((BusinessHour(28, start='21:00', end='02:00'),
  1112. {datetime(2014, 7, 1, 11): datetime(2014, 7, 9, 0),
  1113. datetime(2014, 7, 1, 22): datetime(2014, 7, 9, 1),
  1114. datetime(2014, 7, 1, 23): datetime(2014, 7, 9, 21),
  1115. datetime(2014, 7, 2, 2): datetime(2014, 7, 10, 0),
  1116. datetime(2014, 7, 3, 21): datetime(2014, 7, 11, 0),
  1117. datetime(2014, 7, 4, 1): datetime(2014, 7, 11, 23),
  1118. datetime(2014, 7, 4, 2): datetime(2014, 7, 12, 0),
  1119. datetime(2014, 7, 4, 3): datetime(2014, 7, 12, 0),
  1120. datetime(2014, 7, 5, 1): datetime(2014, 7, 14, 23),
  1121. datetime(2014, 7, 5, 15): datetime(2014, 7, 15, 0),
  1122. datetime(2014, 7, 6, 18): datetime(2014, 7, 15, 0),
  1123. datetime(2014, 7, 7, 1): datetime(2014, 7, 15, 0),
  1124. datetime(2014, 7, 7, 23, 30): datetime(2014, 7, 15, 21,
  1125. 30)}))
  1126. for offset, cases in tests:
  1127. for base, expected in compat.iteritems(cases):
  1128. assertEq(offset, base, expected)
  1129. def test_apply_nanoseconds(self):
  1130. tests = []
  1131. tests.append((BusinessHour(),
  1132. {Timestamp('2014-07-04 15:00') + Nano(5): Timestamp(
  1133. '2014-07-04 16:00') + Nano(5),
  1134. Timestamp('2014-07-04 16:00') + Nano(5): Timestamp(
  1135. '2014-07-07 09:00') + Nano(5),
  1136. Timestamp('2014-07-04 16:00') - Nano(5): Timestamp(
  1137. '2014-07-04 17:00') - Nano(5)}))
  1138. tests.append((BusinessHour(-1),
  1139. {Timestamp('2014-07-04 15:00') + Nano(5): Timestamp(
  1140. '2014-07-04 14:00') + Nano(5),
  1141. Timestamp('2014-07-04 10:00') + Nano(5): Timestamp(
  1142. '2014-07-04 09:00') + Nano(5),
  1143. Timestamp('2014-07-04 10:00') - Nano(5): Timestamp(
  1144. '2014-07-03 17:00') - Nano(5), }))
  1145. for offset, cases in tests:
  1146. for base, expected in compat.iteritems(cases):
  1147. assertEq(offset, base, expected)
  1148. def test_offsets_compare_equal(self):
  1149. # root cause of #456
  1150. offset1 = self._offset()
  1151. offset2 = self._offset()
  1152. self.assertFalse(offset1 != offset2)
  1153. def test_datetimeindex(self):
  1154. idx1 = DatetimeIndex(start='2014-07-04 15:00', end='2014-07-08 10:00',
  1155. freq='BH')
  1156. idx2 = DatetimeIndex(start='2014-07-04 15:00', periods=12, freq='BH')
  1157. idx3 = DatetimeIndex(end='2014-07-08 10:00', periods=12, freq='BH')
  1158. expected = DatetimeIndex(['2014-07-04 15:00', '2014-07-04 16:00',
  1159. '2014-07-07 09:00',
  1160. '2014-07-07 10:00', '2014-07-07 11:00',
  1161. '2014-07-07 12:00',
  1162. '2014-07-07 13:00', '2014-07-07 14:00',
  1163. '2014-07-07 15:00',
  1164. '2014-07-07 16:00', '2014-07-08 09:00',
  1165. '2014-07-08 10:00'],
  1166. freq='BH')
  1167. for idx in [idx1, idx2, idx3]:
  1168. tm.assert_index_equal(idx, expected)
  1169. idx1 = DatetimeIndex(start='2014-07-04 15:45', end='2014-07-08 10:45',
  1170. freq='BH')
  1171. idx2 = DatetimeIndex(start='2014-07-04 15:45', periods=12, freq='BH')
  1172. idx3 = DatetimeIndex(end='2014-07-08 10:45', periods=12, freq='BH')
  1173. expected = DatetimeIndex(['2014-07-04 15:45', '2014-07-04 16:45',
  1174. '2014-07-07 09:45',
  1175. '2014-07-07 10:45', '2014-07-07 11:45',
  1176. '2014-07-07 12:45',
  1177. '2014-07-07 13:45', '2014-07-07 14:45',
  1178. '2014-07-07 15:45',
  1179. '2014-07-07 16:45', '2014-07-08 09:45',
  1180. '2014-07-08 10:45'],
  1181. freq='BH')
  1182. expected = idx1
  1183. for idx in [idx1, idx2, idx3]:
  1184. tm.assert_index_equal(idx, expected)
  1185. class TestCustomBusinessHour(Base):
  1186. _multiprocess_can_split_ = True
  1187. _offset = CustomBusinessHour
  1188. def setUp(self):
  1189. # 2014 Calendar to check custom holidays
  1190. # Sun Mon Tue Wed Thu Fri Sat
  1191. # 6/22 23 24 25 26 27 28
  1192. # 29 30 7/1 2 3 4 5
  1193. # 6 7 8 9 10 11 12
  1194. self.d = datetime(2014, 7, 1, 10, 00)
  1195. self.offset1 = CustomBusinessHour(weekmask='Tue Wed Thu Fri')
  1196. self.holidays = ['2014-06-27', datetime(2014, 6, 30),
  1197. np.datetime64('2014-07-02')]
  1198. self.offset2 = CustomBusinessHour(holidays=self.holidays)
  1199. def test_constructor_errors(self):
  1200. from datetime import time as dt_time
  1201. with tm.assertRaises(ValueError):
  1202. CustomBusinessHour(start=dt_time(11, 0, 5))
  1203. with tm.assertRaises(ValueError):
  1204. CustomBusinessHour(start='AAA')
  1205. with tm.assertRaises(ValueError):
  1206. CustomBusinessHour(start='14:00:05')
  1207. def test_different_normalize_equals(self):
  1208. # equivalent in this special case
  1209. offset = self._offset()
  1210. offset2 = self._offset()
  1211. offset2.normalize = True
  1212. self.assertEqual(offset, offset2)
  1213. def test_repr(self):
  1214. self.assertEqual(repr(self.offset1),
  1215. '<CustomBusinessHour: CBH=09:00-17:00>')
  1216. self.assertEqual(repr(self.offset2),
  1217. '<CustomBusinessHour: CBH=09:00-17:00>')
  1218. def test_with_offset(self):
  1219. expected = Timestamp('2014-07-01 13:00')
  1220. self.assertEqual(self.d + CustomBusinessHour() * 3, expected)
  1221. self.assertEqual(self.d + CustomBusinessHour(n=3), expected)
  1222. def testEQ(self):
  1223. for offset in [self.offset1, self.offset2]:
  1224. self.assertEqual(offset, offset)
  1225. self.assertNotEqual(CustomBusinessHour(), CustomBusinessHour(-1))
  1226. self.assertEqual(CustomBusinessHour(start='09:00'),
  1227. CustomBusinessHour())
  1228. self.assertNotEqual(CustomBusinessHour(start='09:00'),
  1229. CustomBusinessHour(start='09:01'))
  1230. self.assertNotEqual(CustomBusinessHour(start='09:00', end='17:00'),
  1231. CustomBusinessHour(start='17:00', end='09:01'))
  1232. self.assertNotEqual(CustomBusinessHour(weekmask='Tue Wed Thu Fri'),
  1233. CustomBusinessHour(weekmask='Mon Tue Wed Thu Fri'))
  1234. self.assertNotEqual(CustomBusinessHour(holidays=['2014-06-27']),
  1235. CustomBusinessHour(holidays=['2014-06-28']))
  1236. def test_hash(self):
  1237. self.assertEqual(hash(self.offset1), hash(self.offset1))
  1238. self.assertEqual(hash(self.offset2), hash(self.offset2))
  1239. def testCall(self):
  1240. self.assertEqual(self.offset1(self.d), datetime(2014, 7, 1, 11))
  1241. self.assertEqual(self.offset2(self.d), datetime(2014, 7, 1, 11))
  1242. def testRAdd(self):
  1243. self.assertEqual(self.d + self.offset2, self.offset2 + self.d)
  1244. def testSub(self):
  1245. off = self.offset2
  1246. self.assertRaises(Exception, off.__sub__, self.d)
  1247. self.assertEqual(2 * off - off, off)
  1248. self.assertEqual(self.d - self.offset2, self.d - (2 * off - off))
  1249. def testRSub(self):
  1250. self.assertEqual(self.d - self.offset2, (-self.offset2).apply(self.d))
  1251. def testMult1(self):
  1252. self.assertEqual(self.d + 5 * self.offset1, self.d + self._offset(5))
  1253. def testMult2(self):
  1254. self.assertEqual(self.d + (-3 * self._offset(-2)),
  1255. self.d + self._offset(6))
  1256. def testRollback1(self):
  1257. self.assertEqual(self.offset1.rollback(self.d), self.d)
  1258. self.assertEqual(self.offset2.rollback(self.d), self.d)
  1259. d = datetime(2014, 7, 1, 0)
  1260. # 2014/07/01 is Tuesday, 06/30 is Monday(holiday)
  1261. self.assertEqual(self.offset1.rollback(d), datetime(2014, 6, 27, 17))
  1262. # 2014/6/30 and 2014/6/27 are holidays
  1263. self.assertEqual(self.offset2.rollback(d), datetime(2014, 6, 26, 17))
  1264. def testRollback2(self):
  1265. self.assertEqual(self._offset(-3)
  1266. .rollback(datetime(2014, 7, 5, 15, 0)),
  1267. datetime(2014, 7, 4, 17, 0))
  1268. def testRollforward1(self):
  1269. self.assertEqual(self.offset1.rollforward(self.d), self.d)
  1270. self.assertEqual(self.offset2.rollforward(self.d), self.d)
  1271. d = datetime(2014, 7, 1, 0)
  1272. self.assertEqual(self.offset1.rollforward(d), datetime(2014, 7, 1, 9))
  1273. self.assertEqual(self.offset2.rollforward(d), datetime(2014, 7, 1, 9))
  1274. def testRollforward2(self):
  1275. self.assertEqual(self._offset(-3)
  1276. .rollforward(datetime(2014, 7, 5, 16, 0)),
  1277. datetime(2014, 7, 7, 9))
  1278. def test_roll_date_object(self):
  1279. offset = BusinessHour()
  1280. dt = datetime(2014, 7, 6, 15, 0)
  1281. result = offset.rollback(dt)
  1282. self.assertEqual(result, datetime(2014, 7, 4, 17))
  1283. result = offset.rollforward(dt)
  1284. self.assertEqual(result, datetime(2014, 7, 7, 9))
  1285. def test_normalize(self):
  1286. tests = []
  1287. tests.append((CustomBusinessHour(normalize=True,
  1288. holidays=self.holidays),
  1289. {datetime(2014, 7, 1, 8): datetime(2014, 7, 1),
  1290. datetime(2014, 7, 1, 17): datetime(2014, 7, 3),
  1291. datetime(2014, 7, 1, 16): datetime(2014, 7, 3),
  1292. datetime(2014, 7, 1, 23): datetime(2014, 7, 3),
  1293. datetime(2014, 7, 1, 0): datetime(2014, 7, 1),
  1294. datetime(2014, 7, 4, 15): datetime(2014, 7, 4),
  1295. datetime(2014, 7, 4, 15, 59): datetime(2014, 7, 4),
  1296. datetime(2014, 7, 4, 16, 30): datetime(2014, 7, 7),
  1297. datetime(2014, 7, 5, 23): datetime(2014, 7, 7),
  1298. datetime(2014, 7, 6, 10): datetime(2014, 7, 7)}))
  1299. tests.append((CustomBusinessHour(-1, normalize=True,
  1300. holidays=self.holidays),
  1301. {datetime(2014, 7, 1, 8): datetime(2014, 6, 26),
  1302. datetime(2014, 7, 1, 17): datetime(2014, 7, 1),
  1303. datetime(2014, 7, 1, 16): datetime(2014, 7, 1),
  1304. datetime(2014, 7, 1, 10): datetime(2014, 6, 26),
  1305. datetime(2014, 7, 1, 0): datetime(2014, 6, 26),
  1306. datetime(2014, 7, 7, 10): datetime(2014, 7, 4),
  1307. datetime(2014, 7, 7, 10, 1): datetime(2014, 7, 7),
  1308. datetime(2014, 7, 5, 23): datetime(2014, 7, 4),
  1309. datetime(2014, 7, 6, 10): datetime(2014, 7, 4)}))
  1310. tests.append((CustomBusinessHour(1, normalize=True, start='17:00',
  1311. end='04:00', holidays=self.holidays),
  1312. {datetime(2014, 7, 1, 8): datetime(2014, 7, 1),
  1313. datetime(2014, 7, 1, 17): datetime(2014, 7, 1),
  1314. datetime(2014, 7, 1, 23): datetime(2014, 7, 2),
  1315. datetime(2014, 7, 2, 2): datetime(2014, 7, 2),
  1316. datetime(2014, 7, 2, 3): datetime(2014, 7, 3),
  1317. datetime(2014, 7, 4, 23): datetime(2014, 7, 5),
  1318. datetime(2014, 7, 5, 2): datetime(2014, 7, 5),
  1319. datetime(2014, 7, 7, 2): datetime(2014, 7, 7),
  1320. datetime(2014, 7, 7, 17): datetime(2014, 7, 7)}))
  1321. for offset, cases in tests:
  1322. for dt, expected in compat.iteritems(cases):
  1323. self.assertEqual(offset.apply(dt), expected)
  1324. def test_onOffset(self):
  1325. tests = []
  1326. tests.append((CustomBusinessHour(start='10:00', end='15:00',
  1327. holidays=self.holidays),
  1328. {datetime(2014, 7, 1, 9): False,
  1329. datetime(2014, 7, 1, 10): True,
  1330. datetime(2014, 7, 1, 15): True,
  1331. datetime(2014, 7, 1, 15, 1): False,
  1332. datetime(2014, 7, 5, 12): False,
  1333. datetime(2014, 7, 6, 12): False}))
  1334. for offset, cases in tests:
  1335. for dt, expected in compat.iteritems(cases):
  1336. self.assertEqual(offset.onOffset(dt), expected)
  1337. def test_apply(self):
  1338. tests = []
  1339. tests.append((
  1340. CustomBusinessHour(holidays=self.holidays),
  1341. {datetime(2014, 7, 1, 11): datetime(2014, 7, 1, 12),
  1342. datetime(2014, 7, 1, 13): datetime(2014, 7, 1, 14),
  1343. datetime(2014, 7, 1, 15): datetime(2014, 7, 1, 16),
  1344. datetime(2014, 7, 1, 19): datetime(2014, 7, 3, 10),
  1345. datetime(2014, 7, 1, 16): datetime(2014, 7, 3, 9),
  1346. datetime(2014, 7, 1, 16, 30, 15): datetime(2014, 7, 3, 9, 30, 15),
  1347. datetime(2014, 7, 1, 17): datetime(2014, 7, 3, 10),
  1348. datetime(2014, 7, 2, 11): datetime(2014, 7, 3, 10),
  1349. # out of business hours
  1350. datetime(2014, 7, 2, 8): datetime(2014, 7, 3, 10),
  1351. datetime(2014, 7, 2, 19): datetime(2014, 7, 3, 10),
  1352. datetime(2014, 7, 2, 23): datetime(2014, 7, 3, 10),
  1353. datetime(2014, 7, 3, 0): datetime(2014, 7, 3, 10),
  1354. # saturday
  1355. datetime(2014, 7, 5, 15): datetime(2014, 7, 7, 10),
  1356. datetime(2014, 7, 4, 17): datetime(2014, 7, 7, 10),
  1357. datetime(2014, 7, 4, 16, 30): datetime(2014, 7, 7, 9, 30),
  1358. datetime(2014, 7, 4, 16, 30, 30): datetime(2014, 7, 7, 9, 30,
  1359. 30)}))
  1360. tests.append((
  1361. CustomBusinessHour(4, holidays=self.holidays),
  1362. {datetime(2014, 7, 1, 11): datetime(2014, 7, 1, 15),
  1363. datetime(2014, 7, 1, 13): datetime(2014, 7, 3, 9),
  1364. datetime(2014, 7, 1, 15): datetime(2014, 7, 3, 11),
  1365. datetime(2014, 7, 1, 16): datetime(2014, 7, 3, 12),
  1366. datetime(2014, 7, 1, 17): datetime(2014, 7, 3, 13),
  1367. datetime(2014, 7, 2, 11): datetime(2014, 7, 3, 13),
  1368. datetime(2014, 7, 2, 8): datetime(2014, 7, 3, 13),
  1369. datetime(2014, 7, 2, 19): datetime(2014, 7, 3, 13),
  1370. datetime(2014, 7, 2, 23): datetime(2014, 7, 3, 13),
  1371. datetime(2014, 7, 3, 0): datetime(2014, 7, 3, 13),
  1372. datetime(2014, 7, 5, 15): datetime(2014, 7, 7, 13),
  1373. datetime(2014, 7, 4, 17): datetime(2014, 7, 7, 13),
  1374. datetime(2014, 7, 4, 16, 30): datetime(2014, 7, 7, 12, 30),
  1375. datetime(2014, 7, 4, 16, 30, 30): datetime(2014, 7, 7, 12, 30,
  1376. 30)}))
  1377. for offset, cases in tests:
  1378. for base, expected in compat.iteritems(cases):
  1379. assertEq(offset, base, expected)
  1380. def test_apply_nanoseconds(self):
  1381. tests = []
  1382. tests.append((CustomBusinessHour(holidays=self.holidays),
  1383. {Timestamp('2014-07-01 15:00') + Nano(5): Timestamp(
  1384. '2014-07-01 16:00') + Nano(5),
  1385. Timestamp('2014-07-01 16:00') + Nano(5): Timestamp(
  1386. '2014-07-03 09:00') + Nano(5),
  1387. Timestamp('2014-07-01 16:00') - Nano(5): Timestamp(
  1388. '2014-07-01 17:00') - Nano(5)}))
  1389. tests.append((CustomBusinessHour(-1, holidays=self.holidays),
  1390. {Timestamp('2014-07-01 15:00') + Nano(5): Timestamp(
  1391. '2014-07-01 14:00') + Nano(5),
  1392. Timestamp('2014-07-01 10:00') + Nano(5): Timestamp(
  1393. '2014-07-01 09:00') + Nano(5),
  1394. Timestamp('2014-07-01 10:00') - Nano(5): Timestamp(
  1395. '2014-06-26 17:00') - Nano(5), }))
  1396. for offset, cases in tests:
  1397. for base, expected in compat.iteritems(cases):
  1398. assertEq(offset, base, expected)
  1399. class TestCustomBusinessDay(Base):
  1400. _multiprocess_can_split_ = True
  1401. _offset = CDay
  1402. def setUp(self):
  1403. self.d = datetime(2008, 1, 1)
  1404. self.nd = np_datetime64_compat('2008-01-01 00:00:00Z')
  1405. self.offset = CDay()
  1406. self.offset2 = CDay(2)
  1407. def test_different_normalize_equals(self):
  1408. # equivalent in this special case
  1409. offset = CDay()
  1410. offset2 = CDay()
  1411. offset2.normalize = True
  1412. self.assertEqual(offset, offset2)
  1413. def test_repr(self):
  1414. assert repr(self.offset) == '<CustomBusinessDay>'
  1415. assert repr(self.offset2) == '<2 * CustomBusinessDays>'
  1416. expected = '<BusinessDay: offset=datetime.timedelta(1)>'
  1417. assert repr(self.offset + timedelta(1)) == expected
  1418. def test_with_offset(self):
  1419. offset = self.offset + timedelta(hours=2)
  1420. assert (self.d + offset) == datetime(2008, 1, 2, 2)
  1421. def testEQ(self):
  1422. self.assertEqual(self.offset2, self.offset2)
  1423. def test_mul(self):
  1424. pass
  1425. def test_hash(self):
  1426. self.assertEqual(hash(self.offset2), hash(self.offset2))
  1427. def testCall(self):
  1428. self.assertEqual(self.offset2(self.d), datetime(2008, 1, 3))
  1429. self.assertEqual(self.offset2(self.nd), datetime(2008, 1, 3))
  1430. def testRAdd(self):
  1431. self.assertEqual(self.d + self.offset2, self.offset2 + self.d)
  1432. def testSub(self):
  1433. off = self.offset2
  1434. self.assertRaises(Exception, off.__sub__, self.d)
  1435. self.assertEqual(2 * off - off, off)
  1436. self.assertEqual(self.d - self.offset2, self.d + CDay(-2))
  1437. def testRSub(self):
  1438. self.assertEqual(self.d - self.offset2, (-self.offset2).apply(self.d))
  1439. def testMult1(self):
  1440. self.assertEqual(self.d + 10 * self.offset, self.d + CDay(10))
  1441. def testMult2(self):
  1442. self.assertEqual(self.d + (-5 * CDay(-10)), self.d + CDay(50))
  1443. def testRollback1(self):
  1444. self.assertEqual(CDay(10).rollback(self.d), self.d)
  1445. def testRollback2(self):
  1446. self.assertEqual(
  1447. CDay(10).rollback(datetime(2008, 1, 5)), datetime(2008, 1, 4))
  1448. def testRollforward1(self):
  1449. self.assertEqual(CDay(10).rollforward(self.d), self.d)
  1450. def testRollforward2(self):
  1451. self.assertEqual(
  1452. CDay(10).rollforward(datetime(2008, 1, 5)), datetime(2008, 1, 7))
  1453. def test_roll_date_object(self):
  1454. offset = CDay()
  1455. dt = date(2012, 9, 15)
  1456. result = offset.rollback(dt)
  1457. self.assertEqual(result, datetime(2012, 9, 14))
  1458. result = offset.rollforward(dt)
  1459. self.assertEqual(result, datetime(2012, 9, 17))
  1460. offset = offsets.Day()
  1461. result = offset.rollback(dt)
  1462. self.assertEqual(result, datetime(2012, 9, 15))
  1463. result = offset.rollforward(dt)
  1464. self.assertEqual(result, datetime(2012, 9, 15))
  1465. def test_onOffset(self):
  1466. tests = [(CDay(), datetime(2008, 1, 1), True),
  1467. (CDay(), datetime(2008, 1, 5), False)]
  1468. for offset, d, expected in tests:
  1469. assertOnOffset(offset, d, expected)
  1470. def test_apply(self):
  1471. from pandas.core.datetools import cday
  1472. tests = []
  1473. tests.append((cday, {datetime(2008, 1, 1): datetime(2008, 1, 2),
  1474. datetime(2008, 1, 4): datetime(2008, 1, 7),
  1475. datetime(2008, 1, 5): datetime(2008, 1, 7),
  1476. datetime(2008, 1, 6): datetime(2008, 1, 7),
  1477. datetime(2008, 1, 7): datetime(2008, 1, 8)}))
  1478. tests.append((2 * cday, {datetime(2008, 1, 1): datetime(2008, 1, 3),
  1479. datetime(2008, 1, 4): datetime(2008, 1, 8),
  1480. datetime(2008, 1, 5): datetime(2008, 1, 8),
  1481. datetime(2008, 1, 6): datetime(2008, 1, 8),
  1482. datetime(2008, 1, 7): datetime(2008, 1, 9)}))
  1483. tests.append((-cday, {datetime(2008, 1, 1): datetime(2007, 12, 31),
  1484. datetime(2008, 1, 4): datetime(2008, 1, 3),
  1485. datetime(2008, 1, 5): datetime(2008, 1, 4),
  1486. datetime(2008, 1, 6): datetime(2008, 1, 4),
  1487. datetime(2008, 1, 7): datetime(2008, 1, 4),
  1488. datetime(2008, 1, 8): datetime(2008, 1, 7)}))
  1489. tests.append((-2 * cday, {datetime(2008, 1, 1): datetime(2007, 12, 28),
  1490. datetime(2008, 1, 4): datetime(2008, 1, 2),
  1491. datetime(2008, 1, 5): datetime(2008, 1, 3),
  1492. datetime(2008, 1, 6): datetime(2008, 1, 3),
  1493. datetime(2008, 1, 7): datetime(2008, 1, 3),
  1494. datetime(2008, 1, 8): datetime(2008, 1, 4),
  1495. datetime(2008, 1, 9): datetime(2008, 1, 7)}))
  1496. tests.append((CDay(0), {datetime(2008, 1, 1): datetime(2008, 1, 1),
  1497. datetime(2008, 1, 4): datetime(2008, 1, 4),
  1498. datetime(2008, 1, 5): datetime(2008, 1, 7),
  1499. datetime(2008, 1, 6): datetime(2008, 1, 7),
  1500. datetime(2008, 1, 7): datetime(2008, 1, 7)}))
  1501. for offset, cases in tests:
  1502. for base, expected in compat.iteritems(cases):
  1503. assertEq(offset, base, expected)
  1504. def test_apply_large_n(self):
  1505. dt = datetime(2012, 10, 23)
  1506. result = dt + CDay(10)
  1507. self.assertEqual(result, datetime(2012, 11, 6))
  1508. result = dt + CDay(100) - CDay(100)
  1509. self.assertEqual(result, dt)
  1510. off = CDay() * 6
  1511. rs = datetime(2012, 1, 1) - off
  1512. xp = datetime(2011, 12, 23)
  1513. self.assertEqual(rs, xp)
  1514. st = datetime(2011, 12, 18)
  1515. rs = st + off
  1516. xp = datetime(2011, 12, 26)
  1517. self.assertEqual(rs, xp)
  1518. def test_apply_corner(self):
  1519. self.assertRaises(Exception, CDay().apply, BMonthEnd())
  1520. def test_offsets_compare_equal(self):
  1521. # root cause of #456
  1522. offset1 = CDay()
  1523. offset2 = CDay()
  1524. self.assertFalse(offset1 != offset2)
  1525. def test_holidays(self):
  1526. # Define a TradingDay offset
  1527. holidays = ['2012-05-01', datetime(2013, 5, 1),
  1528. np.datetime64('2014-05-01')]
  1529. tday = CDay(holidays=holidays)
  1530. for year in range(2012, 2015):
  1531. dt = datetime(year, 4, 30)
  1532. xp = datetime(year, 5, 2)
  1533. rs = dt + tday
  1534. self.assertEqual(rs, xp)
  1535. def test_weekmask(self):
  1536. weekmask_saudi = 'Sat Sun Mon Tue Wed' # Thu-Fri Weekend
  1537. weekmask_uae = '1111001' # Fri-Sat Weekend
  1538. weekmask_egypt = [1, 1, 1, 1, 0, 0, 1] # Fri-Sat Weekend
  1539. bday_saudi = CDay(weekmask=weekmask_saudi)
  1540. bday_uae = CDay(weekmask=weekmask_uae)
  1541. bday_egypt = CDay(weekmask=weekmask_egypt)
  1542. dt = datetime(2013, 5, 1)
  1543. xp_saudi = datetime(2013, 5, 4)
  1544. xp_uae = datetime(2013, 5, 2)
  1545. xp_egypt = datetime(2013, 5, 2)
  1546. self.assertEqual(xp_saudi, dt + bday_saudi)
  1547. self.assertEqual(xp_uae, dt + bday_uae)
  1548. self.assertEqual(xp_egypt, dt + bday_egypt)
  1549. xp2 = datetime(2013, 5, 5)
  1550. self.assertEqual(xp2, dt + 2 * bday_saudi)
  1551. self.assertEqual(xp2, dt + 2 * bday_uae)
  1552. self.assertEqual(xp2, dt + 2 * bday_egypt)
  1553. def test_weekmask_and_holidays(self):
  1554. weekmask_egypt = 'Sun Mon Tue Wed Thu' # Fri-Sat Weekend
  1555. holidays = ['2012-05-01', datetime(2013, 5, 1),
  1556. np.datetime64('2014-05-01')]
  1557. bday_egypt = CDay(holidays=holidays, weekmask=weekmask_egypt)
  1558. dt = datetime(2013, 4, 30)
  1559. xp_egypt = datetime(2013, 5, 5)
  1560. self.assertEqual(xp_egypt, dt + 2 * bday_egypt)
  1561. def test_calendar(self):
  1562. calendar = USFederalHolidayCalendar()
  1563. dt = datetime(2014, 1, 17)
  1564. assertEq(CDay(calendar=calendar), dt, datetime(2014, 1, 21))
  1565. def test_roundtrip_pickle(self):
  1566. def _check_roundtrip(obj):
  1567. unpickled = self.round_trip_pickle(obj)
  1568. self.assertEqual(unpickled, obj)
  1569. _check_roundtrip(self.offset)
  1570. _check_roundtrip(self.offset2)
  1571. _check_roundtrip(self.offset * 2)
  1572. def test_pickle_compat_0_14_1(self):
  1573. hdays = [datetime(2013, 1, 1) for ele in range(4)]
  1574. pth = tm.get_data_path()
  1575. cday0_14_1 = read_pickle(os.path.join(pth, 'cday-0.14.1.pickle'))
  1576. cday = CDay(holidays=hdays)
  1577. self.assertEqual(cday, cday0_14_1)
  1578. class CustomBusinessMonthBase(object):
  1579. _multiprocess_can_split_ = True
  1580. def setUp(self):
  1581. self.d = datetime(2008, 1, 1)
  1582. self.offset = self._object()
  1583. self.offset2 = self._object(2)
  1584. def testEQ(self):
  1585. self.assertEqual(self.offset2, self.offset2)
  1586. def test_mul(self):
  1587. pass
  1588. def test_hash(self):
  1589. self.assertEqual(hash(self.offset2), hash(self.offset2))
  1590. def testRAdd(self):
  1591. self.assertEqual(self.d + self.offset2, self.offset2 + self.d)
  1592. def testSub(self):
  1593. off = self.offset2
  1594. self.assertRaises(Exception, off.__sub__, self.d)
  1595. self.assertEqual(2 * off - off, off)
  1596. self.assertEqual(self.d - self.offset2, self.d + self._object(-2))
  1597. def testRSub(self):
  1598. self.assertEqual(self.d - self.offset2, (-self.offset2).apply(self.d))
  1599. def testMult1(self):
  1600. self.assertEqual(self.d + 10 * self.offset, self.d + self._object(10))
  1601. def testMult2(self):
  1602. self.assertEqual(self.d + (-5 * self._object(-10)),
  1603. self.d + self._object(50))
  1604. def test_offsets_compare_equal(self):
  1605. offset1 = self._object()
  1606. offset2 = self._object()
  1607. self.assertFalse(offset1 != offset2)
  1608. def test_roundtrip_pickle(self):
  1609. def _check_roundtrip(obj):
  1610. unpickled = self.round_trip_pickle(obj)
  1611. self.assertEqual(unpickled, obj)
  1612. _check_roundtrip(self._object())
  1613. _check_roundtrip(self._object(2))
  1614. _check_roundtrip(self._object() * 2)
  1615. class TestCustomBusinessMonthEnd(CustomBusinessMonthBase, Base):
  1616. _object = CBMonthEnd
  1617. def test_different_normalize_equals(self):
  1618. # equivalent in this special case
  1619. offset = CBMonthEnd()
  1620. offset2 = CBMonthEnd()
  1621. offset2.normalize = True
  1622. self.assertEqual(offset, offset2)
  1623. def test_repr(self):
  1624. assert repr(self.offset) == '<CustomBusinessMonthEnd>'
  1625. assert repr(self.offset2) == '<2 * CustomBusinessMonthEnds>'
  1626. def testCall(self):
  1627. self.assertEqual(self.offset2(self.d), datetime(2008, 2, 29))
  1628. def testRollback1(self):
  1629. self.assertEqual(
  1630. CDay(10).rollback(datetime(2007, 12, 31)), datetime(2007, 12, 31))
  1631. def testRollback2(self):
  1632. self.assertEqual(CBMonthEnd(10).rollback(self.d),
  1633. datetime(2007, 12, 31))
  1634. def testRollforward1(self):
  1635. self.assertEqual(CBMonthEnd(10).rollforward(
  1636. self.d), datetime(2008, 1, 31))
  1637. def test_roll_date_object(self):
  1638. offset = CBMonthEnd()
  1639. dt = date(2012, 9, 15)
  1640. result = offset.rollback(dt)
  1641. self.assertEqual(result, datetime(2012, 8, 31))
  1642. result = offset.rollforward(dt)
  1643. self.assertEqual(result, datetime(2012, 9, 28))
  1644. offset = offsets.Day()
  1645. result = offset.rollback(dt)
  1646. self.assertEqual(result, datetime(2012, 9, 15))
  1647. result = offset.rollforward(dt)
  1648. self.assertEqual(result, datetime(2012, 9, 15))
  1649. def test_onOffset(self):
  1650. tests = [(CBMonthEnd(), datetime(2008, 1, 31), True),
  1651. (CBMonthEnd(), datetime(2008, 1, 1), False)]
  1652. for offset, d, expected in tests:
  1653. assertOnOffset(offset, d, expected)
  1654. def test_apply(self):
  1655. cbm = CBMonthEnd()
  1656. tests = []
  1657. tests.append((cbm, {datetime(2008, 1, 1): datetime(2008, 1, 31),
  1658. datetime(2008, 2, 7): datetime(2008, 2, 29)}))
  1659. tests.append((2 * cbm, {datetime(2008, 1, 1): datetime(2008, 2, 29),
  1660. datetime(2008, 2, 7): datetime(2008, 3, 31)}))
  1661. tests.append((-cbm, {datetime(2008, 1, 1): datetime(2007, 12, 31),
  1662. datetime(2008, 2, 8): datetime(2008, 1, 31)}))
  1663. tests.append((-2 * cbm, {datetime(2008, 1, 1): datetime(2007, 11, 30),
  1664. datetime(2008, 2, 9): datetime(2007, 12, 31)}
  1665. ))
  1666. tests.append((CBMonthEnd(0),
  1667. {datetime(2008, 1, 1): datetime(2008, 1, 31),
  1668. datetime(2008, 2, 7): datetime(2008, 2, 29)}))
  1669. for offset, cases in tests:
  1670. for base, expected in compat.iteritems(cases):
  1671. assertEq(offset, base, expected)
  1672. def test_apply_large_n(self):
  1673. dt = datetime(2012, 10, 23)
  1674. result = dt + CBMonthEnd(10)
  1675. self.assertEqual(result, datetime(2013, 7, 31))
  1676. result = dt + CDay(100) - CDay(100)
  1677. self.assertEqual(result, dt)
  1678. off = CBMonthEnd() * 6
  1679. rs = datetime(2012, 1, 1) - off
  1680. xp = datetime(2011, 7, 29)
  1681. self.assertEqual(rs, xp)
  1682. st = datetime(2011, 12, 18)
  1683. rs = st + off
  1684. xp = datetime(2012, 5, 31)
  1685. self.assertEqual(rs, xp)
  1686. def test_holidays(self):
  1687. # Define a TradingDay offset
  1688. holidays = ['2012-01-31', datetime(2012, 2, 28),
  1689. np.datetime64('2012-02-29')]
  1690. bm_offset = CBMonthEnd(holidays=holidays)
  1691. dt = datetime(2012, 1, 1)
  1692. self.assertEqual(dt + bm_offset, datetime(2012, 1, 30))
  1693. self.assertEqual(dt + 2 * bm_offset, datetime(2012, 2, 27))
  1694. def test_datetimeindex(self):
  1695. from pandas.tseries.holiday import USFederalHolidayCalendar
  1696. hcal = USFederalHolidayCalendar()
  1697. freq = CBMonthEnd(calendar=hcal)
  1698. self.assertEqual(DatetimeIndex(start='20120101', end='20130101',
  1699. freq=freq).tolist()[0],
  1700. datetime(2012, 1, 31))
  1701. class TestCustomBusinessMonthBegin(CustomBusinessMonthBase, Base):
  1702. _object = CBMonthBegin
  1703. def test_different_normalize_equals(self):
  1704. # equivalent in this special case
  1705. offset = CBMonthBegin()
  1706. offset2 = CBMonthBegin()
  1707. offset2.normalize = True
  1708. self.assertEqual(offset, offset2)
  1709. def test_repr(self):
  1710. assert repr(self.offset) == '<CustomBusinessMonthBegin>'
  1711. assert repr(self.offset2) == '<2 * CustomBusinessMonthBegins>'
  1712. def testCall(self):
  1713. self.assertEqual(self.offset2(self.d), datetime(2008, 3, 3))
  1714. def testRollback1(self):
  1715. self.assertEqual(
  1716. CDay(10).rollback(datetime(2007, 12, 31)), datetime(2007, 12, 31))
  1717. def testRollback2(self):
  1718. self.assertEqual(CBMonthBegin(10).rollback(self.d),
  1719. datetime(2008, 1, 1))
  1720. def testRollforward1(self):
  1721. self.assertEqual(CBMonthBegin(10).rollforward(
  1722. self.d), datetime(2008, 1, 1))
  1723. def test_roll_date_object(self):
  1724. offset = CBMonthBegin()
  1725. dt = date(2012, 9, 15)
  1726. result = offset.rollback(dt)
  1727. self.assertEqual(result, datetime(2012, 9, 3))
  1728. result = offset.rollforward(dt)
  1729. self.assertEqual(result, datetime(2012, 10, 1))
  1730. offset = offsets.Day()
  1731. result = offset.rollback(dt)
  1732. self.assertEqual(result, datetime(2012, 9, 15))
  1733. result = offset.rollforward(dt)
  1734. self.assertEqual(result, datetime(2012, 9, 15))
  1735. def test_onOffset(self):
  1736. tests = [(CBMonthBegin(), datetime(2008, 1, 1), True),
  1737. (CBMonthBegin(), datetime(2008, 1, 31), False)]
  1738. for offset, dt, expected in tests:
  1739. assertOnOffset(offset, dt, expected)
  1740. def test_apply(self):
  1741. cbm = CBMonthBegin()
  1742. tests = []
  1743. tests.append((cbm, {datetime(2008, 1, 1): datetime(2008, 2, 1),
  1744. datetime(2008, 2, 7): datetime(2008, 3, 3)}))
  1745. tests.append((2 * cbm, {datetime(2008, 1, 1): datetime(2008, 3, 3),
  1746. datetime(2008, 2, 7): datetime(2008, 4, 1)}))
  1747. tests.append((-cbm, {datetime(2008, 1, 1): datetime(2007, 12, 3),
  1748. datetime(2008, 2, 8): datetime(2008, 2, 1)}))
  1749. tests.append((-2 * cbm, {datetime(2008, 1, 1): datetime(2007, 11, 1),
  1750. datetime(2008, 2, 9): datetime(2008, 1, 1)}))
  1751. tests.append((CBMonthBegin(0),
  1752. {datetime(2008, 1, 1): datetime(2008, 1, 1),
  1753. datetime(2008, 1, 7): datetime(2008, 2, 1)}))
  1754. for offset, cases in tests:
  1755. for base, expected in compat.iteritems(cases):
  1756. assertEq(offset, base, expected)
  1757. def test_apply_large_n(self):
  1758. dt = datetime(2012, 10, 23)
  1759. result = dt + CBMonthBegin(10)
  1760. self.assertEqual(result, datetime(2013, 8, 1))
  1761. result = dt + CDay(100) - CDay(100)
  1762. self.assertEqual(result, dt)
  1763. off = CBMonthBegin() * 6
  1764. rs = datetime(2012, 1, 1) - off
  1765. xp = datetime(2011, 7, 1)
  1766. self.assertEqual(rs, xp)
  1767. st = datetime(2011, 12, 18)
  1768. rs = st + off
  1769. xp = datetime(2012, 6, 1)
  1770. self.assertEqual(rs, xp)
  1771. def test_holidays(self):
  1772. # Define a TradingDay offset
  1773. holidays = ['2012-02-01', datetime(2012, 2, 2),
  1774. np.datetime64('2012-03-01')]
  1775. bm_offset = CBMonthBegin(holidays=holidays)
  1776. dt = datetime(2012, 1, 1)
  1777. self.assertEqual(dt + bm_offset, datetime(2012, 1, 2))
  1778. self.assertEqual(dt + 2 * bm_offset, datetime(2012, 2, 3))
  1779. def test_datetimeindex(self):
  1780. hcal = USFederalHolidayCalendar()
  1781. cbmb = CBMonthBegin(calendar=hcal)
  1782. self.assertEqual(DatetimeIndex(start='20120101', end='20130101',
  1783. freq=cbmb).tolist()[0],
  1784. datetime(2012, 1, 3))
  1785. def assertOnOffset(offset, date, expected):
  1786. actual = offset.onOffset(date)
  1787. assert actual == expected, ("\nExpected: %s\nActual: %s\nFor Offset: %s)"
  1788. "\nAt Date: %s" %
  1789. (expected, actual, offset, date))
  1790. class TestWeek(Base):
  1791. _offset = Week
  1792. def test_repr(self):
  1793. self.assertEqual(repr(Week(weekday=0)), "<Week: weekday=0>")
  1794. self.assertEqual(repr(Week(n=-1, weekday=0)), "<-1 * Week: weekday=0>")
  1795. self.assertEqual(repr(Week(n=-2, weekday=0)),
  1796. "<-2 * Weeks: weekday=0>")
  1797. def test_corner(self):
  1798. self.assertRaises(ValueError, Week, weekday=7)
  1799. assertRaisesRegexp(ValueError, "Day must be", Week, weekday=-1)
  1800. def test_isAnchored(self):
  1801. self.assertTrue(Week(weekday=0).isAnchored())
  1802. self.assertFalse(Week().isAnchored())
  1803. self.assertFalse(Week(2, weekday=2).isAnchored())
  1804. self.assertFalse(Week(2).isAnchored())
  1805. def test_offset(self):
  1806. tests = []
  1807. tests.append((Week(), # not business week
  1808. {datetime(2008, 1, 1): datetime(2008, 1, 8),
  1809. datetime(2008, 1, 4): datetime(2008, 1, 11),
  1810. datetime(2008, 1, 5): datetime(2008, 1, 12),
  1811. datetime(2008, 1, 6): datetime(2008, 1, 13),
  1812. datetime(2008, 1, 7): datetime(2008, 1, 14)}))
  1813. tests.append((Week(weekday=0), # Mon
  1814. {datetime(2007, 12, 31): datetime(2008, 1, 7),
  1815. datetime(2008, 1, 4): datetime(2008, 1, 7),
  1816. datetime(2008, 1, 5): datetime(2008, 1, 7),
  1817. datetime(2008, 1, 6): datetime(2008, 1, 7),
  1818. datetime(2008, 1, 7): datetime(2008, 1, 14)}))
  1819. tests.append((Week(0, weekday=0), # n=0 -> roll forward. Mon
  1820. {datetime(2007, 12, 31): datetime(2007, 12, 31),
  1821. datetime(2008, 1, 4): datetime(2008, 1, 7),
  1822. datetime(2008, 1, 5): datetime(2008, 1, 7),
  1823. datetime(2008, 1, 6): datetime(2008, 1, 7),
  1824. datetime(2008, 1, 7): datetime(2008, 1, 7)}))
  1825. tests.append((Week(-2, weekday=1), # n=0 -> roll forward. Mon
  1826. {datetime(2010, 4, 6): datetime(2010, 3, 23),
  1827. datetime(2010, 4, 8): datetime(2010, 3, 30),
  1828. datetime(2010, 4, 5): datetime(2010, 3, 23)}))
  1829. for offset, cases in tests:
  1830. for base, expected in compat.iteritems(cases):
  1831. assertEq(offset, base, expected)
  1832. def test_onOffset(self):
  1833. for weekday in range(7):
  1834. offset = Week(weekday=weekday)
  1835. for day in range(1, 8):
  1836. date = datetime(2008, 1, day)
  1837. if day % 7 == weekday:
  1838. expected = True
  1839. else:
  1840. expected = False
  1841. assertOnOffset(offset, date, expected)
  1842. def test_offsets_compare_equal(self):
  1843. # root cause of #456
  1844. offset1 = Week()
  1845. offset2 = Week()
  1846. self.assertFalse(offset1 != offset2)
  1847. class TestWeekOfMonth(Base):
  1848. _offset = WeekOfMonth
  1849. def test_constructor(self):
  1850. assertRaisesRegexp(ValueError, "^N cannot be 0", WeekOfMonth, n=0,
  1851. week=1, weekday=1)
  1852. assertRaisesRegexp(ValueError, "^Week", WeekOfMonth, n=1, week=4,
  1853. weekday=0)
  1854. assertRaisesRegexp(ValueError, "^Week", WeekOfMonth, n=1, week=-1,
  1855. weekday=0)
  1856. assertRaisesRegexp(ValueError, "^Day", WeekOfMonth, n=1, week=0,
  1857. weekday=-1)
  1858. assertRaisesRegexp(ValueError, "^Day", WeekOfMonth, n=1, week=0,
  1859. weekday=7)
  1860. def test_repr(self):
  1861. self.assertEqual(repr(WeekOfMonth(weekday=1, week=2)),
  1862. "<WeekOfMonth: week=2, weekday=1>")
  1863. def test_offset(self):
  1864. date1 = datetime(2011, 1, 4) # 1st Tuesday of Month
  1865. date2 = datetime(2011, 1, 11) # 2nd Tuesday of Month
  1866. date3 = datetime(2011, 1, 18) # 3rd Tuesday of Month
  1867. date4 = datetime(2011, 1, 25) # 4th Tuesday of Month
  1868. # see for loop for structure
  1869. test_cases = [
  1870. (-2, 2, 1, date1, datetime(2010, 11, 16)),
  1871. (-2, 2, 1, date2, datetime(2010, 11, 16)),
  1872. (-2, 2, 1, date3, datetime(2010, 11, 16)),
  1873. (-2, 2, 1, date4, datetime(2010, 12, 21)),
  1874. (-1, 2, 1, date1, datetime(2010, 12, 21)),
  1875. (-1, 2, 1, date2, datetime(2010, 12, 21)),
  1876. (-1, 2, 1, date3, datetime(2010, 12, 21)),
  1877. (-1, 2, 1, date4, datetime(2011, 1, 18)),
  1878. (1, 0, 0, date1, datetime(2011, 2, 7)),
  1879. (1, 0, 0, date2, datetime(2011, 2, 7)),
  1880. (1, 0, 0, date3, datetime(2011, 2, 7)),
  1881. (1, 0, 0, date4, datetime(2011, 2, 7)),
  1882. (1, 0, 1, date1, datetime(2011, 2, 1)),
  1883. (1, 0, 1, date2, datetime(2011, 2, 1)),
  1884. (1, 0, 1, date3, datetime(2011, 2, 1)),
  1885. (1, 0, 1, date4, datetime(2011, 2, 1)),
  1886. (1, 0, 2, date1, datetime(2011, 1, 5)),
  1887. (1, 0, 2, date2, datetime(2011, 2, 2)),
  1888. (1, 0, 2, date3, datetime(2011, 2, 2)),
  1889. (1, 0, 2, date4, datetime(2011, 2, 2)),
  1890. (1, 2, 1, date1, datetime(2011, 1, 18)),
  1891. (1, 2, 1, date2, datetime(2011, 1, 18)),
  1892. (1, 2, 1, date3, datetime(2011, 2, 15)),
  1893. (1, 2, 1, date4, datetime(2011, 2, 15)),
  1894. (2, 2, 1, date1, datetime(2011, 2, 15)),
  1895. (2, 2, 1, date2, datetime(2011, 2, 15)),
  1896. (2, 2, 1, date3, datetime(2011, 3, 15)),
  1897. (2, 2, 1, date4, datetime(2011, 3, 15)),
  1898. ]
  1899. for n, week, weekday, dt, expected in test_cases:
  1900. offset = WeekOfMonth(n, week=week, weekday=weekday)
  1901. assertEq(offset, dt, expected)
  1902. # try subtracting
  1903. result = datetime(2011, 2, 1) - WeekOfMonth(week=1, weekday=2)
  1904. self.assertEqual(result, datetime(2011, 1, 12))
  1905. result = datetime(2011, 2, 3) - WeekOfMonth(week=0, weekday=2)
  1906. self.assertEqual(result, datetime(2011, 2, 2))
  1907. def test_onOffset(self):
  1908. test_cases = [
  1909. (0, 0, datetime(2011, 2, 7), True),
  1910. (0, 0, datetime(2011, 2, 6), False),
  1911. (0, 0, datetime(2011, 2, 14), False),
  1912. (1, 0, datetime(2011, 2, 14), True),
  1913. (0, 1, datetime(2011, 2, 1), True),
  1914. (0, 1, datetime(2011, 2, 8), False),
  1915. ]
  1916. for week, weekday, dt, expected in test_cases:
  1917. offset = WeekOfMonth(week=week, weekday=weekday)
  1918. self.assertEqual(offset.onOffset(dt), expected)
  1919. class TestLastWeekOfMonth(Base):
  1920. _offset = LastWeekOfMonth
  1921. def test_constructor(self):
  1922. assertRaisesRegexp(ValueError, "^N cannot be 0", LastWeekOfMonth, n=0,
  1923. weekday=1)
  1924. assertRaisesRegexp(ValueError, "^Day", LastWeekOfMonth, n=1,
  1925. weekday=-1)
  1926. assertRaisesRegexp(ValueError, "^Day", LastWeekOfMonth, n=1, weekday=7)
  1927. def test_offset(self):
  1928. # Saturday
  1929. last_sat = datetime(2013, 8, 31)
  1930. next_sat = datetime(2013, 9, 28)
  1931. offset_sat = LastWeekOfMonth(n=1, weekday=5)
  1932. one_day_before = (last_sat + timedelta(days=-1))
  1933. self.assertEqual(one_day_before + offset_sat, last_sat)
  1934. one_day_after = (last_sat + timedelta(days=+1))
  1935. self.assertEqual(one_day_after + offset_sat, next_sat)
  1936. # Test On that day
  1937. self.assertEqual(last_sat + offset_sat, next_sat)
  1938. # Thursday
  1939. offset_thur = LastWeekOfMonth(n=1, weekday=3)
  1940. last_thurs = datetime(2013, 1, 31)
  1941. next_thurs = datetime(2013, 2, 28)
  1942. one_day_before = last_thurs + timedelta(days=-1)
  1943. self.assertEqual(one_day_before + offset_thur, last_thurs)
  1944. one_day_after = last_thurs + timedelta(days=+1)
  1945. self.assertEqual(one_day_after + offset_thur, next_thurs)
  1946. # Test on that day
  1947. self.assertEqual(last_thurs + offset_thur, next_thurs)
  1948. three_before = last_thurs + timedelta(days=-3)
  1949. self.assertEqual(three_before + offset_thur, last_thurs)
  1950. two_after = last_thurs + timedelta(days=+2)
  1951. self.assertEqual(two_after + offset_thur, next_thurs)
  1952. offset_sunday = LastWeekOfMonth(n=1, weekday=WeekDay.SUN)
  1953. self.assertEqual(datetime(2013, 7, 31) +
  1954. offset_sunday, datetime(2013, 8, 25))
  1955. def test_onOffset(self):
  1956. test_cases = [
  1957. (WeekDay.SUN, datetime(2013, 1, 27), True),
  1958. (WeekDay.SAT, datetime(2013, 3, 30), True),
  1959. (WeekDay.MON, datetime(2013, 2, 18), False), # Not the last Mon
  1960. (WeekDay.SUN, datetime(2013, 2, 25), False), # Not a SUN
  1961. (WeekDay.MON, datetime(2013, 2, 25), True),
  1962. (WeekDay.SAT, datetime(2013, 11, 30), True),
  1963. (WeekDay.SAT, datetime(2006, 8, 26), True),
  1964. (WeekDay.SAT, datetime(2007, 8, 25), True),
  1965. (WeekDay.SAT, datetime(2008, 8, 30), True),
  1966. (WeekDay.SAT, datetime(2009, 8, 29), True),
  1967. (WeekDay.SAT, datetime(2010, 8, 28), True),
  1968. (WeekDay.SAT, datetime(2011, 8, 27), True),
  1969. (WeekDay.SAT, datetime(2019, 8, 31), True),
  1970. ]
  1971. for weekday, dt, expected in test_cases:
  1972. offset = LastWeekOfMonth(weekday=weekday)
  1973. self.assertEqual(offset.onOffset(dt), expected, msg=date)
  1974. class TestBMonthBegin(Base):
  1975. _offset = BMonthBegin
  1976. def test_offset(self):
  1977. tests = []
  1978. tests.append((BMonthBegin(),
  1979. {datetime(2008, 1, 1): datetime(2008, 2, 1),
  1980. datetime(2008, 1, 31): datetime(2008, 2, 1),
  1981. datetime(2006, 12, 29): datetime(2007, 1, 1),
  1982. datetime(2006, 12, 31): datetime(2007, 1, 1),
  1983. datetime(2006, 9, 1): datetime(2006, 10, 2),
  1984. datetime(2007, 1, 1): datetime(2007, 2, 1),
  1985. datetime(2006, 12, 1): datetime(2007, 1, 1)}))
  1986. tests.append((BMonthBegin(0),
  1987. {datetime(2008, 1, 1): datetime(2008, 1, 1),
  1988. datetime(2006, 10, 2): datetime(2006, 10, 2),
  1989. datetime(2008, 1, 31): datetime(2008, 2, 1),
  1990. datetime(2006, 12, 29): datetime(2007, 1, 1),
  1991. datetime(2006, 12, 31): datetime(2007, 1, 1),
  1992. datetime(2006, 9, 15): datetime(2006, 10, 2)}))
  1993. tests.append((BMonthBegin(2),
  1994. {datetime(2008, 1, 1): datetime(2008, 3, 3),
  1995. datetime(2008, 1, 15): datetime(2008, 3, 3),
  1996. datetime(2006, 12, 29): datetime(2007, 2, 1),
  1997. datetime(2006, 12, 31): datetime(2007, 2, 1),
  1998. datetime(2007, 1, 1): datetime(2007, 3, 1),
  1999. datetime(2006, 11, 1): datetime(2007, 1, 1)}))
  2000. tests.append((BMonthBegin(-1),
  2001. {datetime(2007, 1, 1): datetime(2006, 12, 1),
  2002. datetime(2008, 6, 30): datetime(2008, 6, 2),
  2003. datetime(2008, 6, 1): datetime(2008, 5, 1),
  2004. datetime(2008, 3, 10): datetime(2008, 3, 3),
  2005. datetime(2008, 12, 31): datetime(2008, 12, 1),
  2006. datetime(2006, 12, 29): datetime(2006, 12, 1),
  2007. datetime(2006, 12, 30): datetime(2006, 12, 1),
  2008. datetime(2007, 1, 1): datetime(2006, 12, 1)}))
  2009. for offset, cases in tests:
  2010. for base, expected in compat.iteritems(cases):
  2011. assertEq(offset, base, expected)
  2012. def test_onOffset(self):
  2013. tests = [(BMonthBegin(), datetime(2007, 12, 31), False),
  2014. (BMonthBegin(), datetime(2008, 1, 1), True),
  2015. (BMonthBegin(), datetime(2001, 4, 2), True),
  2016. (BMonthBegin(), datetime(2008, 3, 3), True)]
  2017. for offset, dt, expected in tests:
  2018. assertOnOffset(offset, dt, expected)
  2019. def test_offsets_compare_equal(self):
  2020. # root cause of #456
  2021. offset1 = BMonthBegin()
  2022. offset2 = BMonthBegin()
  2023. self.assertFalse(offset1 != offset2)
  2024. class TestBMonthEnd(Base):
  2025. _offset = BMonthEnd
  2026. def test_offset(self):
  2027. tests = []
  2028. tests.append((BMonthEnd(),
  2029. {datetime(2008, 1, 1): datetime(2008, 1, 31),
  2030. datetime(2008, 1, 31): datetime(2008, 2, 29),
  2031. datetime(2006, 12, 29): datetime(2007, 1, 31),
  2032. datetime(2006, 12, 31): datetime(2007, 1, 31),
  2033. datetime(2007, 1, 1): datetime(2007, 1, 31),
  2034. datetime(2006, 12, 1): datetime(2006, 12, 29)}))
  2035. tests.append((BMonthEnd(0),
  2036. {datetime(2008, 1, 1): datetime(2008, 1, 31),
  2037. datetime(2008, 1, 31): datetime(2008, 1, 31),
  2038. datetime(2006, 12, 29): datetime(2006, 12, 29),
  2039. datetime(2006, 12, 31): datetime(2007, 1, 31),
  2040. datetime(2007, 1, 1): datetime(2007, 1, 31)}))
  2041. tests.append((BMonthEnd(2),
  2042. {datetime(2008, 1, 1): datetime(2008, 2, 29),
  2043. datetime(2008, 1, 31): datetime(2008, 3, 31),
  2044. datetime(2006, 12, 29): datetime(2007, 2, 28),
  2045. datetime(2006, 12, 31): datetime(2007, 2, 28),
  2046. datetime(2007, 1, 1): datetime(2007, 2, 28),
  2047. datetime(2006, 11, 1): datetime(2006, 12, 29)}))
  2048. tests.append((BMonthEnd(-1),
  2049. {datetime(2007, 1, 1): datetime(2006, 12, 29),
  2050. datetime(2008, 6, 30): datetime(2008, 5, 30),
  2051. datetime(2008, 12, 31): datetime(2008, 11, 28),
  2052. datetime(2006, 12, 29): datetime(2006, 11, 30),
  2053. datetime(2006, 12, 30): datetime(2006, 12, 29),
  2054. datetime(2007, 1, 1): datetime(2006, 12, 29)}))
  2055. for offset, cases in tests:
  2056. for base, expected in compat.iteritems(cases):
  2057. assertEq(offset, base, expected)
  2058. def test_normalize(self):
  2059. dt = datetime(2007, 1, 1, 3)
  2060. result = dt + BMonthEnd(normalize=True)
  2061. expected = dt.replace(hour=0) + BMonthEnd()
  2062. self.assertEqual(result, expected)
  2063. def test_onOffset(self):
  2064. tests = [(BMonthEnd(), datetime(2007, 12, 31), True),
  2065. (BMonthEnd(), datetime(2008, 1, 1), False)]
  2066. for offset, dt, expected in tests:
  2067. assertOnOffset(offset, dt, expected)
  2068. def test_offsets_compare_equal(self):
  2069. # root cause of #456
  2070. offset1 = BMonthEnd()
  2071. offset2 = BMonthEnd()
  2072. self.assertFalse(offset1 != offset2)
  2073. class TestMonthBegin(Base):
  2074. _offset = MonthBegin
  2075. def test_offset(self):
  2076. tests = []
  2077. # NOTE: I'm not entirely happy with the logic here for Begin -ss
  2078. # see thread 'offset conventions' on the ML
  2079. tests.append((MonthBegin(),
  2080. {datetime(2008, 1, 31): datetime(2008, 2, 1),
  2081. datetime(2008, 2, 1): datetime(2008, 3, 1),
  2082. datetime(2006, 12, 31): datetime(2007, 1, 1),
  2083. datetime(2006, 12, 1): datetime(2007, 1, 1),
  2084. datetime(2007, 1, 31): datetime(2007, 2, 1)}))
  2085. tests.append((MonthBegin(0),
  2086. {datetime(2008, 1, 31): datetime(2008, 2, 1),
  2087. datetime(2008, 1, 1): datetime(2008, 1, 1),
  2088. datetime(2006, 12, 3): datetime(2007, 1, 1),
  2089. datetime(2007, 1, 31): datetime(2007, 2, 1)}))
  2090. tests.append((MonthBegin(2),
  2091. {datetime(2008, 2, 29): datetime(2008, 4, 1),
  2092. datetime(2008, 1, 31): datetime(2008, 3, 1),
  2093. datetime(2006, 12, 31): datetime(2007, 2, 1),
  2094. datetime(2007, 12, 28): datetime(2008, 2, 1),
  2095. datetime(2007, 1, 1): datetime(2007, 3, 1),
  2096. datetime(2006, 11, 1): datetime(2007, 1, 1)}))
  2097. tests.append((MonthBegin(-1),
  2098. {datetime(2007, 1, 1): datetime(2006, 12, 1),
  2099. datetime(2008, 5, 31): datetime(2008, 5, 1),
  2100. datetime(2008, 12, 31): datetime(2008, 12, 1),
  2101. datetime(2006, 12, 29): datetime(2006, 12, 1),
  2102. datetime(2006, 1, 2): datetime(2006, 1, 1)}))
  2103. for offset, cases in tests:
  2104. for base, expected in compat.iteritems(cases):
  2105. assertEq(offset, base, expected)
  2106. class TestMonthEnd(Base):
  2107. _offset = MonthEnd
  2108. def test_offset(self):
  2109. tests = []
  2110. tests.append((MonthEnd(),
  2111. {datetime(2008, 1, 1): datetime(2008, 1, 31),
  2112. datetime(2008, 1, 31): datetime(2008, 2, 29),
  2113. datetime(2006, 12, 29): datetime(2006, 12, 31),
  2114. datetime(2006, 12, 31): datetime(2007, 1, 31),
  2115. datetime(2007, 1, 1): datetime(2007, 1, 31),
  2116. datetime(2006, 12, 1): datetime(2006, 12, 31)}))
  2117. tests.append((MonthEnd(0),
  2118. {datetime(2008, 1, 1): datetime(2008, 1, 31),
  2119. datetime(2008, 1, 31): datetime(2008, 1, 31),
  2120. datetime(2006, 12, 29): datetime(2006, 12, 31),
  2121. datetime(2006, 12, 31): datetime(2006, 12, 31),
  2122. datetime(2007, 1, 1): datetime(2007, 1, 31)}))
  2123. tests.append((MonthEnd(2),
  2124. {datetime(2008, 1, 1): datetime(2008, 2, 29),
  2125. datetime(2008, 1, 31): datetime(2008, 3, 31),
  2126. datetime(2006, 12, 29): datetime(2007, 1, 31),
  2127. datetime(2006, 12, 31): datetime(2007, 2, 28),
  2128. datetime(2007, 1, 1): datetime(2007, 2, 28),
  2129. datetime(2006, 11, 1): datetime(2006, 12, 31)}))
  2130. tests.append((MonthEnd(-1),
  2131. {datetime(2007, 1, 1): datetime(2006, 12, 31),
  2132. datetime(2008, 6, 30): datetime(2008, 5, 31),
  2133. datetime(2008, 12, 31): datetime(2008, 11, 30),
  2134. datetime(2006, 12, 29): datetime(2006, 11, 30),
  2135. datetime(2006, 12, 30): datetime(2006, 11, 30),
  2136. datetime(2007, 1, 1): datetime(2006, 12, 31)}))
  2137. for offset, cases in tests:
  2138. for base, expected in compat.iteritems(cases):
  2139. assertEq(offset, base, expected)
  2140. # def test_day_of_month(self):
  2141. # dt = datetime(2007, 1, 1)
  2142. # offset = MonthEnd(day=20)
  2143. # result = dt + offset
  2144. # self.assertEqual(result, datetime(2007, 1, 20))
  2145. # result = result + offset
  2146. # self.assertEqual(result, datetime(2007, 2, 20))
  2147. def test_normalize(self):
  2148. dt = datetime(2007, 1, 1, 3)
  2149. result = dt + MonthEnd(normalize=True)
  2150. expected = dt.replace(hour=0) + MonthEnd()
  2151. self.assertEqual(result, expected)
  2152. def test_onOffset(self):
  2153. tests = [(MonthEnd(), datetime(2007, 12, 31), True),
  2154. (MonthEnd(), datetime(2008, 1, 1), False)]
  2155. for offset, dt, expected in tests:
  2156. assertOnOffset(offset, dt, expected)
  2157. class TestSemiMonthEnd(Base):
  2158. _offset = SemiMonthEnd
  2159. def _get_tests(self):
  2160. tests = []
  2161. tests.append((SemiMonthEnd(),
  2162. {datetime(2008, 1, 1): datetime(2008, 1, 15),
  2163. datetime(2008, 1, 15): datetime(2008, 1, 31),
  2164. datetime(2008, 1, 31): datetime(2008, 2, 15),
  2165. datetime(2006, 12, 14): datetime(2006, 12, 15),
  2166. datetime(2006, 12, 29): datetime(2006, 12, 31),
  2167. datetime(2006, 12, 31): datetime(2007, 1, 15),
  2168. datetime(2007, 1, 1): datetime(2007, 1, 15),
  2169. datetime(2006, 12, 1): datetime(2006, 12, 15),
  2170. datetime(2006, 12, 15): datetime(2006, 12, 31)}))
  2171. tests.append((SemiMonthEnd(day_of_month=20),
  2172. {datetime(2008, 1, 1): datetime(2008, 1, 20),
  2173. datetime(2008, 1, 15): datetime(2008, 1, 20),
  2174. datetime(2008, 1, 21): datetime(2008, 1, 31),
  2175. datetime(2008, 1, 31): datetime(2008, 2, 20),
  2176. datetime(2006, 12, 14): datetime(2006, 12, 20),
  2177. datetime(2006, 12, 29): datetime(2006, 12, 31),
  2178. datetime(2006, 12, 31): datetime(2007, 1, 20),
  2179. datetime(2007, 1, 1): datetime(2007, 1, 20),
  2180. datetime(2006, 12, 1): datetime(2006, 12, 20),
  2181. datetime(2006, 12, 15): datetime(2006, 12, 20)}))
  2182. tests.append((SemiMonthEnd(0),
  2183. {datetime(2008, 1, 1): datetime(2008, 1, 15),
  2184. datetime(2008, 1, 16): datetime(2008, 1, 31),
  2185. datetime(2008, 1, 15): datetime(2008, 1, 15),
  2186. datetime(2008, 1, 31): datetime(2008, 1, 31),
  2187. datetime(2006, 12, 29): datetime(2006, 12, 31),
  2188. datetime(2006, 12, 31): datetime(2006, 12, 31),
  2189. datetime(2007, 1, 1): datetime(2007, 1, 15)}))
  2190. tests.append((SemiMonthEnd(0, day_of_month=16),
  2191. {datetime(2008, 1, 1): datetime(2008, 1, 16),
  2192. datetime(2008, 1, 16): datetime(2008, 1, 16),
  2193. datetime(2008, 1, 15): datetime(2008, 1, 16),
  2194. datetime(2008, 1, 31): datetime(2008, 1, 31),
  2195. datetime(2006, 12, 29): datetime(2006, 12, 31),
  2196. datetime(2006, 12, 31): datetime(2006, 12, 31),
  2197. datetime(2007, 1, 1): datetime(2007, 1, 16)}))
  2198. tests.append((SemiMonthEnd(2),
  2199. {datetime(2008, 1, 1): datetime(2008, 1, 31),
  2200. datetime(2008, 1, 31): datetime(2008, 2, 29),
  2201. datetime(2006, 12, 29): datetime(2007, 1, 15),
  2202. datetime(2006, 12, 31): datetime(2007, 1, 31),
  2203. datetime(2007, 1, 1): datetime(2007, 1, 31),
  2204. datetime(2007, 1, 16): datetime(2007, 2, 15),
  2205. datetime(2006, 11, 1): datetime(2006, 11, 30)}))
  2206. tests.append((SemiMonthEnd(-1),
  2207. {datetime(2007, 1, 1): datetime(2006, 12, 31),
  2208. datetime(2008, 6, 30): datetime(2008, 6, 15),
  2209. datetime(2008, 12, 31): datetime(2008, 12, 15),
  2210. datetime(2006, 12, 29): datetime(2006, 12, 15),
  2211. datetime(2006, 12, 30): datetime(2006, 12, 15),
  2212. datetime(2007, 1, 1): datetime(2006, 12, 31)}))
  2213. tests.append((SemiMonthEnd(-1, day_of_month=4),
  2214. {datetime(2007, 1, 1): datetime(2006, 12, 31),
  2215. datetime(2007, 1, 4): datetime(2006, 12, 31),
  2216. datetime(2008, 6, 30): datetime(2008, 6, 4),
  2217. datetime(2008, 12, 31): datetime(2008, 12, 4),
  2218. datetime(2006, 12, 5): datetime(2006, 12, 4),
  2219. datetime(2006, 12, 30): datetime(2006, 12, 4),
  2220. datetime(2007, 1, 1): datetime(2006, 12, 31)}))
  2221. tests.append((SemiMonthEnd(-2),
  2222. {datetime(2007, 1, 1): datetime(2006, 12, 15),
  2223. datetime(2008, 6, 30): datetime(2008, 5, 31),
  2224. datetime(2008, 3, 15): datetime(2008, 2, 15),
  2225. datetime(2008, 12, 31): datetime(2008, 11, 30),
  2226. datetime(2006, 12, 29): datetime(2006, 11, 30),
  2227. datetime(2006, 12, 14): datetime(2006, 11, 15),
  2228. datetime(2007, 1, 1): datetime(2006, 12, 15)}))
  2229. return tests
  2230. def test_offset_whole_year(self):
  2231. dates = (datetime(2007, 12, 31),
  2232. datetime(2008, 1, 15),
  2233. datetime(2008, 1, 31),
  2234. datetime(2008, 2, 15),
  2235. datetime(2008, 2, 29),
  2236. datetime(2008, 3, 15),
  2237. datetime(2008, 3, 31),
  2238. datetime(2008, 4, 15),
  2239. datetime(2008, 4, 30),
  2240. datetime(2008, 5, 15),
  2241. datetime(2008, 5, 31),
  2242. datetime(2008, 6, 15),
  2243. datetime(2008, 6, 30),
  2244. datetime(2008, 7, 15),
  2245. datetime(2008, 7, 31),
  2246. datetime(2008, 8, 15),
  2247. datetime(2008, 8, 31),
  2248. datetime(2008, 9, 15),
  2249. datetime(2008, 9, 30),
  2250. datetime(2008, 10, 15),
  2251. datetime(2008, 10, 31),
  2252. datetime(2008, 11, 15),
  2253. datetime(2008, 11, 30),
  2254. datetime(2008, 12, 15),
  2255. datetime(2008, 12, 31))
  2256. for base, exp_date in zip(dates[:-1], dates[1:]):
  2257. assertEq(SemiMonthEnd(), base, exp_date)
  2258. # ensure .apply_index works as expected
  2259. s = DatetimeIndex(dates[:-1])
  2260. result = SemiMonthEnd().apply_index(s)
  2261. exp = DatetimeIndex(dates[1:])
  2262. tm.assert_index_equal(result, exp)
  2263. # ensure generating a range with DatetimeIndex gives same result
  2264. result = DatetimeIndex(start=dates[0], end=dates[-1], freq='SM')
  2265. exp = DatetimeIndex(dates)
  2266. tm.assert_index_equal(result, exp)
  2267. def test_offset(self):
  2268. for offset, cases in self._get_tests():
  2269. for base, expected in compat.iteritems(cases):
  2270. assertEq(offset, base, expected)
  2271. def test_apply_index(self):
  2272. for offset, cases in self._get_tests():
  2273. s = DatetimeIndex(cases.keys())
  2274. result = offset.apply_index(s)
  2275. exp = DatetimeIndex(cases.values())
  2276. tm.assert_index_equal(result, exp)
  2277. def test_onOffset(self):
  2278. tests = [(datetime(2007, 12, 31), True),
  2279. (datetime(2007, 12, 15), True),
  2280. (datetime(2007, 12, 14), False),
  2281. (datetime(2007, 12, 1), False),
  2282. (datetime(2008, 2, 29), True)]
  2283. for dt, expected in tests:
  2284. assertOnOffset(SemiMonthEnd(), dt, expected)
  2285. def test_vectorized_offset_addition(self):
  2286. for klass, assert_func in zip([Series, DatetimeIndex],
  2287. [self.assert_series_equal,
  2288. tm.assert_index_equal]):
  2289. s = klass([Timestamp('2000-01-15 00:15:00', tz='US/Central'),
  2290. Timestamp('2000-02-15', tz='US/Central')], name='a')
  2291. result = s + SemiMonthEnd()
  2292. result2 = SemiMonthEnd() + s
  2293. exp = klass([Timestamp('2000-01-31 00:15:00', tz='US/Central'),
  2294. Timestamp('2000-02-29', tz='US/Central')], name='a')
  2295. assert_func(result, exp)
  2296. assert_func(result2, exp)
  2297. s = klass([Timestamp('2000-01-01 00:15:00', tz='US/Central'),
  2298. Timestamp('2000-02-01', tz='US/Central')], name='a')
  2299. result = s + SemiMonthEnd()
  2300. result2 = SemiMonthEnd() + s
  2301. exp = klass([Timestamp('2000-01-15 00:15:00', tz='US/Central'),
  2302. Timestamp('2000-02-15', tz='US/Central')], name='a')
  2303. assert_func(result, exp)
  2304. assert_func(result2, exp)
  2305. class TestSemiMonthBegin(Base):
  2306. _offset = SemiMonthBegin
  2307. def _get_tests(self):
  2308. tests = []
  2309. tests.append((SemiMonthBegin(),
  2310. {datetime(2008, 1, 1): datetime(2008, 1, 15),
  2311. datetime(2008, 1, 15): datetime(2008, 2, 1),
  2312. datetime(2008, 1, 31): datetime(2008, 2, 1),
  2313. datetime(2006, 12, 14): datetime(2006, 12, 15),
  2314. datetime(2006, 12, 29): datetime(2007, 1, 1),
  2315. datetime(2006, 12, 31): datetime(2007, 1, 1),
  2316. datetime(2007, 1, 1): datetime(2007, 1, 15),
  2317. datetime(2006, 12, 1): datetime(2006, 12, 15),
  2318. datetime(2006, 12, 15): datetime(2007, 1, 1)}))
  2319. tests.append((SemiMonthBegin(day_of_month=20),
  2320. {datetime(2008, 1, 1): datetime(2008, 1, 20),
  2321. datetime(2008, 1, 15): datetime(2008, 1, 20),
  2322. datetime(2008, 1, 21): datetime(2008, 2, 1),
  2323. datetime(2008, 1, 31): datetime(2008, 2, 1),
  2324. datetime(2006, 12, 14): datetime(2006, 12, 20),
  2325. datetime(2006, 12, 29): datetime(2007, 1, 1),
  2326. datetime(2006, 12, 31): datetime(2007, 1, 1),
  2327. datetime(2007, 1, 1): datetime(2007, 1, 20),
  2328. datetime(2006, 12, 1): datetime(2006, 12, 20),
  2329. datetime(2006, 12, 15): datetime(2006, 12, 20)}))
  2330. tests.append((SemiMonthBegin(0),
  2331. {datetime(2008, 1, 1): datetime(2008, 1, 1),
  2332. datetime(2008, 1, 16): datetime(2008, 2, 1),
  2333. datetime(2008, 1, 15): datetime(2008, 1, 15),
  2334. datetime(2008, 1, 31): datetime(2008, 2, 1),
  2335. datetime(2006, 12, 29): datetime(2007, 1, 1),
  2336. datetime(2006, 12, 2): datetime(2006, 12, 15),
  2337. datetime(2007, 1, 1): datetime(2007, 1, 1)}))
  2338. tests.append((SemiMonthBegin(0, day_of_month=16),
  2339. {datetime(2008, 1, 1): datetime(2008, 1, 1),
  2340. datetime(2008, 1, 16): datetime(2008, 1, 16),
  2341. datetime(2008, 1, 15): datetime(2008, 1, 16),
  2342. datetime(2008, 1, 31): datetime(2008, 2, 1),
  2343. datetime(2006, 12, 29): datetime(2007, 1, 1),
  2344. datetime(2006, 12, 31): datetime(2007, 1, 1),
  2345. datetime(2007, 1, 5): datetime(2007, 1, 16),
  2346. datetime(2007, 1, 1): datetime(2007, 1, 1)}))
  2347. tests.append((SemiMonthBegin(2),
  2348. {datetime(2008, 1, 1): datetime(2008, 2, 1),
  2349. datetime(2008, 1, 31): datetime(2008, 2, 15),
  2350. datetime(2006, 12, 1): datetime(2007, 1, 1),
  2351. datetime(2006, 12, 29): datetime(2007, 1, 15),
  2352. datetime(2006, 12, 15): datetime(2007, 1, 15),
  2353. datetime(2007, 1, 1): datetime(2007, 2, 1),
  2354. datetime(2007, 1, 16): datetime(2007, 2, 15),
  2355. datetime(2006, 11, 1): datetime(2006, 12, 1)}))
  2356. tests.append((SemiMonthBegin(-1),
  2357. {datetime(2007, 1, 1): datetime(2006, 12, 15),
  2358. datetime(2008, 6, 30): datetime(2008, 6, 15),
  2359. datetime(2008, 6, 14): datetime(2008, 6, 1),
  2360. datetime(2008, 12, 31): datetime(2008, 12, 15),
  2361. datetime(2006, 12, 29): datetime(2006, 12, 15),
  2362. datetime(2006, 12, 15): datetime(2006, 12, 1),
  2363. datetime(2007, 1, 1): datetime(2006, 12, 15)}))
  2364. tests.append((SemiMonthBegin(-1, day_of_month=4),
  2365. {datetime(2007, 1, 1): datetime(2006, 12, 4),
  2366. datetime(2007, 1, 4): datetime(2007, 1, 1),
  2367. datetime(2008, 6, 30): datetime(2008, 6, 4),
  2368. datetime(2008, 12, 31): datetime(2008, 12, 4),
  2369. datetime(2006, 12, 5): datetime(2006, 12, 4),
  2370. datetime(2006, 12, 30): datetime(2006, 12, 4),
  2371. datetime(2006, 12, 2): datetime(2006, 12, 1),
  2372. datetime(2007, 1, 1): datetime(2006, 12, 4)}))
  2373. tests.append((SemiMonthBegin(-2),
  2374. {datetime(2007, 1, 1): datetime(2006, 12, 1),
  2375. datetime(2008, 6, 30): datetime(2008, 6, 1),
  2376. datetime(2008, 6, 14): datetime(2008, 5, 15),
  2377. datetime(2008, 12, 31): datetime(2008, 12, 1),
  2378. datetime(2006, 12, 29): datetime(2006, 12, 1),
  2379. datetime(2006, 12, 15): datetime(2006, 11, 15),
  2380. datetime(2007, 1, 1): datetime(2006, 12, 1)}))
  2381. return tests
  2382. def test_offset_whole_year(self):
  2383. dates = (datetime(2007, 12, 15),
  2384. datetime(2008, 1, 1),
  2385. datetime(2008, 1, 15),
  2386. datetime(2008, 2, 1),
  2387. datetime(2008, 2, 15),
  2388. datetime(2008, 3, 1),
  2389. datetime(2008, 3, 15),
  2390. datetime(2008, 4, 1),
  2391. datetime(2008, 4, 15),
  2392. datetime(2008, 5, 1),
  2393. datetime(2008, 5, 15),
  2394. datetime(2008, 6, 1),
  2395. datetime(2008, 6, 15),
  2396. datetime(2008, 7, 1),
  2397. datetime(2008, 7, 15),
  2398. datetime(2008, 8, 1),
  2399. datetime(2008, 8, 15),
  2400. datetime(2008, 9, 1),
  2401. datetime(2008, 9, 15),
  2402. datetime(2008, 10, 1),
  2403. datetime(2008, 10, 15),
  2404. datetime(2008, 11, 1),
  2405. datetime(2008, 11, 15),
  2406. datetime(2008, 12, 1),
  2407. datetime(2008, 12, 15))
  2408. for base, exp_date in zip(dates[:-1], dates[1:]):
  2409. assertEq(SemiMonthBegin(), base, exp_date)
  2410. # ensure .apply_index works as expected
  2411. s = DatetimeIndex(dates[:-1])
  2412. result = SemiMonthBegin().apply_index(s)
  2413. exp = DatetimeIndex(dates[1:])
  2414. tm.assert_index_equal(result, exp)
  2415. # ensure generating a range with DatetimeIndex gives same result
  2416. result = DatetimeIndex(start=dates[0], end=dates[-1], freq='SMS')
  2417. exp = DatetimeIndex(dates)
  2418. tm.assert_index_equal(result, exp)
  2419. def test_offset(self):
  2420. for offset, cases in self._get_tests():
  2421. for base, expected in compat.iteritems(cases):
  2422. assertEq(offset, base, expected)
  2423. def test_apply_index(self):
  2424. for offset, cases in self._get_tests():
  2425. s = DatetimeIndex(cases.keys())
  2426. result = offset.apply_index(s)
  2427. exp = DatetimeIndex(cases.values())
  2428. tm.assert_index_equal(result, exp)
  2429. def test_onOffset(self):
  2430. tests = [(datetime(2007, 12, 1), True),
  2431. (datetime(2007, 12, 15), True),
  2432. (datetime(2007, 12, 14), False),
  2433. (datetime(2007, 12, 31), False),
  2434. (datetime(2008, 2, 15), True)]
  2435. for dt, expected in tests:
  2436. assertOnOffset(SemiMonthBegin(), dt, expected)
  2437. def test_vectorized_offset_addition(self):
  2438. for klass, assert_func in zip([Series, DatetimeIndex],
  2439. [self.assert_series_equal,
  2440. tm.assert_index_equal]):
  2441. s = klass([Timestamp('2000-01-15 00:15:00', tz='US/Central'),
  2442. Timestamp('2000-02-15', tz='US/Central')], name='a')
  2443. result = s + SemiMonthBegin()
  2444. result2 = SemiMonthBegin() + s
  2445. exp = klass([Timestamp('2000-02-01 00:15:00', tz='US/Central'),
  2446. Timestamp('2000-03-01', tz='US/Central')], name='a')
  2447. assert_func(result, exp)
  2448. assert_func(result2, exp)
  2449. s = klass([Timestamp('2000-01-01 00:15:00', tz='US/Central'),
  2450. Timestamp('2000-02-01', tz='US/Central')], name='a')
  2451. result = s + SemiMonthBegin()
  2452. result2 = SemiMonthBegin() + s
  2453. exp = klass([Timestamp('2000-01-15 00:15:00', tz='US/Central'),
  2454. Timestamp('2000-02-15', tz='US/Central')], name='a')
  2455. assert_func(result, exp)
  2456. assert_func(result2, exp)
  2457. class TestBQuarterBegin(Base):
  2458. _offset = BQuarterBegin
  2459. def test_repr(self):
  2460. self.assertEqual(repr(BQuarterBegin()),
  2461. "<BusinessQuarterBegin: startingMonth=3>")
  2462. self.assertEqual(repr(BQuarterBegin(startingMonth=3)),
  2463. "<BusinessQuarterBegin: startingMonth=3>")
  2464. self.assertEqual(repr(BQuarterBegin(startingMonth=1)),
  2465. "<BusinessQuarterBegin: startingMonth=1>")
  2466. def test_isAnchored(self):
  2467. self.assertTrue(BQuarterBegin(startingMonth=1).isAnchored())
  2468. self.assertTrue(BQuarterBegin().isAnchored())
  2469. self.assertFalse(BQuarterBegin(2, startingMonth=1).isAnchored())
  2470. def test_offset(self):
  2471. tests = []
  2472. tests.append((BQuarterBegin(startingMonth=1),
  2473. {datetime(2008, 1, 1): datetime(2008, 4, 1),
  2474. datetime(2008, 1, 31): datetime(2008, 4, 1),
  2475. datetime(2008, 2, 15): datetime(2008, 4, 1),
  2476. datetime(2008, 2, 29): datetime(2008, 4, 1),
  2477. datetime(2008, 3, 15): datetime(2008, 4, 1),
  2478. datetime(2008, 3, 31): datetime(2008, 4, 1),
  2479. datetime(2008, 4, 15): datetime(2008, 7, 1),
  2480. datetime(2007, 3, 15): datetime(2007, 4, 2),
  2481. datetime(2007, 2, 28): datetime(2007, 4, 2),
  2482. datetime(2007, 1, 1): datetime(2007, 4, 2),
  2483. datetime(2007, 4, 15): datetime(2007, 7, 2),
  2484. datetime(2007, 7, 1): datetime(2007, 7, 2),
  2485. datetime(2007, 4, 1): datetime(2007, 4, 2),
  2486. datetime(2007, 4, 2): datetime(2007, 7, 2),
  2487. datetime(2008, 4, 30): datetime(2008, 7, 1), }))
  2488. tests.append((BQuarterBegin(startingMonth=2),
  2489. {datetime(2008, 1, 1): datetime(2008, 2, 1),
  2490. datetime(2008, 1, 31): datetime(2008, 2, 1),
  2491. datetime(2008, 1, 15): datetime(2008, 2, 1),
  2492. datetime(2008, 2, 29): datetime(2008, 5, 1),
  2493. datetime(2008, 3, 15): datetime(2008, 5, 1),
  2494. datetime(2008, 3, 31): datetime(2008, 5, 1),
  2495. datetime(2008, 4, 15): datetime(2008, 5, 1),
  2496. datetime(2008, 8, 15): datetime(2008, 11, 3),
  2497. datetime(2008, 9, 15): datetime(2008, 11, 3),
  2498. datetime(2008, 11, 1): datetime(2008, 11, 3),
  2499. datetime(2008, 4, 30): datetime(2008, 5, 1), }))
  2500. tests.append((BQuarterBegin(startingMonth=1, n=0),
  2501. {datetime(2008, 1, 1): datetime(2008, 1, 1),
  2502. datetime(2007, 12, 31): datetime(2008, 1, 1),
  2503. datetime(2008, 2, 15): datetime(2008, 4, 1),
  2504. datetime(2008, 2, 29): datetime(2008, 4, 1),
  2505. datetime(2008, 1, 15): datetime(2008, 4, 1),
  2506. datetime(2008, 2, 27): datetime(2008, 4, 1),
  2507. datetime(2008, 3, 15): datetime(2008, 4, 1),
  2508. datetime(2007, 4, 1): datetime(2007, 4, 2),
  2509. datetime(2007, 4, 2): datetime(2007, 4, 2),
  2510. datetime(2007, 7, 1): datetime(2007, 7, 2),
  2511. datetime(2007, 4, 15): datetime(2007, 7, 2),
  2512. datetime(2007, 7, 2): datetime(2007, 7, 2), }))
  2513. tests.append((BQuarterBegin(startingMonth=1, n=-1),
  2514. {datetime(2008, 1, 1): datetime(2007, 10, 1),
  2515. datetime(2008, 1, 31): datetime(2008, 1, 1),
  2516. datetime(2008, 2, 15): datetime(2008, 1, 1),
  2517. datetime(2008, 2, 29): datetime(2008, 1, 1),
  2518. datetime(2008, 3, 15): datetime(2008, 1, 1),
  2519. datetime(2008, 3, 31): datetime(2008, 1, 1),
  2520. datetime(2008, 4, 15): datetime(2008, 4, 1),
  2521. datetime(2007, 7, 3): datetime(2007, 7, 2),
  2522. datetime(2007, 4, 3): datetime(2007, 4, 2),
  2523. datetime(2007, 7, 2): datetime(2007, 4, 2),
  2524. datetime(2008, 4, 1): datetime(2008, 1, 1), }))
  2525. tests.append((BQuarterBegin(startingMonth=1, n=2),
  2526. {datetime(2008, 1, 1): datetime(2008, 7, 1),
  2527. datetime(2008, 1, 15): datetime(2008, 7, 1),
  2528. datetime(2008, 2, 29): datetime(2008, 7, 1),
  2529. datetime(2008, 3, 15): datetime(2008, 7, 1),
  2530. datetime(2007, 3, 31): datetime(2007, 7, 2),
  2531. datetime(2007, 4, 15): datetime(2007, 10, 1),
  2532. datetime(2008, 4, 30): datetime(2008, 10, 1), }))
  2533. for offset, cases in tests:
  2534. for base, expected in compat.iteritems(cases):
  2535. assertEq(offset, base, expected)
  2536. # corner
  2537. offset = BQuarterBegin(n=-1, startingMonth=1)
  2538. self.assertEqual(datetime(2007, 4, 3) + offset, datetime(2007, 4, 2))
  2539. class TestBQuarterEnd(Base):
  2540. _offset = BQuarterEnd
  2541. def test_repr(self):
  2542. self.assertEqual(repr(BQuarterEnd()),
  2543. "<BusinessQuarterEnd: startingMonth=3>")
  2544. self.assertEqual(repr(BQuarterEnd(startingMonth=3)),
  2545. "<BusinessQuarterEnd: startingMonth=3>")
  2546. self.assertEqual(repr(BQuarterEnd(startingMonth=1)),
  2547. "<BusinessQuarterEnd: startingMonth=1>")
  2548. def test_isAnchored(self):
  2549. self.assertTrue(BQuarterEnd(startingMonth=1).isAnchored())
  2550. self.assertTrue(BQuarterEnd().isAnchored())
  2551. self.assertFalse(BQuarterEnd(2, startingMonth=1).isAnchored())
  2552. def test_offset(self):
  2553. tests = []
  2554. tests.append((BQuarterEnd(startingMonth=1),
  2555. {datetime(2008, 1, 1): datetime(2008, 1, 31),
  2556. datetime(2008, 1, 31): datetime(2008, 4, 30),
  2557. datetime(2008, 2, 15): datetime(2008, 4, 30),
  2558. datetime(2008, 2, 29): datetime(2008, 4, 30),
  2559. datetime(2008, 3, 15): datetime(2008, 4, 30),
  2560. datetime(2008, 3, 31): datetime(2008, 4, 30),
  2561. datetime(2008, 4, 15): datetime(2008, 4, 30),
  2562. datetime(2008, 4, 30): datetime(2008, 7, 31), }))
  2563. tests.append((BQuarterEnd(startingMonth=2),
  2564. {datetime(2008, 1, 1): datetime(2008, 2, 29),
  2565. datetime(2008, 1, 31): datetime(2008, 2, 29),
  2566. datetime(2008, 2, 15): datetime(2008, 2, 29),
  2567. datetime(2008, 2, 29): datetime(2008, 5, 30),
  2568. datetime(2008, 3, 15): datetime(2008, 5, 30),
  2569. datetime(2008, 3, 31): datetime(2008, 5, 30),
  2570. datetime(2008, 4, 15): datetime(2008, 5, 30),
  2571. datetime(2008, 4, 30): datetime(2008, 5, 30), }))
  2572. tests.append((BQuarterEnd(startingMonth=1, n=0),
  2573. {datetime(2008, 1, 1): datetime(2008, 1, 31),
  2574. datetime(2008, 1, 31): datetime(2008, 1, 31),
  2575. datetime(2008, 2, 15): datetime(2008, 4, 30),
  2576. datetime(2008, 2, 29): datetime(2008, 4, 30),
  2577. datetime(2008, 3, 15): datetime(2008, 4, 30),
  2578. datetime(2008, 3, 31): datetime(2008, 4, 30),
  2579. datetime(2008, 4, 15): datetime(2008, 4, 30),
  2580. datetime(2008, 4, 30): datetime(2008, 4, 30), }))
  2581. tests.append((BQuarterEnd(startingMonth=1, n=-1),
  2582. {datetime(2008, 1, 1): datetime(2007, 10, 31),
  2583. datetime(2008, 1, 31): datetime(2007, 10, 31),
  2584. datetime(2008, 2, 15): datetime(2008, 1, 31),
  2585. datetime(2008, 2, 29): datetime(2008, 1, 31),
  2586. datetime(2008, 3, 15): datetime(2008, 1, 31),
  2587. datetime(2008, 3, 31): datetime(2008, 1, 31),
  2588. datetime(2008, 4, 15): datetime(2008, 1, 31),
  2589. datetime(2008, 4, 30): datetime(2008, 1, 31), }))
  2590. tests.append((BQuarterEnd(startingMonth=1, n=2),
  2591. {datetime(2008, 1, 31): datetime(2008, 7, 31),
  2592. datetime(2008, 2, 15): datetime(2008, 7, 31),
  2593. datetime(2008, 2, 29): datetime(2008, 7, 31),
  2594. datetime(2008, 3, 15): datetime(2008, 7, 31),
  2595. datetime(2008, 3, 31): datetime(2008, 7, 31),
  2596. datetime(2008, 4, 15): datetime(2008, 7, 31),
  2597. datetime(2008, 4, 30): datetime(2008, 10, 31), }))
  2598. for offset, cases in tests:
  2599. for base, expected in compat.iteritems(cases):
  2600. assertEq(offset, base, expected)
  2601. # corner
  2602. offset = BQuarterEnd(n=-1, startingMonth=1)
  2603. self.assertEqual(datetime(2010, 1, 31) + offset, datetime(2010, 1, 29))
  2604. def test_onOffset(self):
  2605. tests = [
  2606. (BQuarterEnd(1, startingMonth=1), datetime(2008, 1, 31), True),
  2607. (BQuarterEnd(1, startingMonth=1), datetime(2007, 12, 31), False),
  2608. (BQuarterEnd(1, startingMonth=1), datetime(2008, 2, 29), False),
  2609. (BQuarterEnd(1, startingMonth=1), datetime(2007, 3, 30), False),
  2610. (BQuarterEnd(1, startingMonth=1), datetime(2007, 3, 31), False),
  2611. (BQuarterEnd(1, startingMonth=1), datetime(2008, 4, 30), True),
  2612. (BQuarterEnd(1, startingMonth=1), datetime(2008, 5, 30), False),
  2613. (BQuarterEnd(1, startingMonth=1), datetime(2007, 6, 29), False),
  2614. (BQuarterEnd(1, startingMonth=1), datetime(2007, 6, 30), False),
  2615. (BQuarterEnd(1, startingMonth=2), datetime(2008, 1, 31), False),
  2616. (BQuarterEnd(1, startingMonth=2), datetime(2007, 12, 31), False),
  2617. (BQuarterEnd(1, startingMonth=2), datetime(2008, 2, 29), True),
  2618. (BQuarterEnd(1, startingMonth=2), datetime(2007, 3, 30), False),
  2619. (BQuarterEnd(1, startingMonth=2), datetime(2007, 3, 31), False),
  2620. (BQuarterEnd(1, startingMonth=2), datetime(2008, 4, 30), False),
  2621. (BQuarterEnd(1, startingMonth=2), datetime(2008, 5, 30), True),
  2622. (BQuarterEnd(1, startingMonth=2), datetime(2007, 6, 29), False),
  2623. (BQuarterEnd(1, startingMonth=2), datetime(2007, 6, 30), False),
  2624. (BQuarterEnd(1, startingMonth=3), datetime(2008, 1, 31), False),
  2625. (BQuarterEnd(1, startingMonth=3), datetime(2007, 12, 31), True),
  2626. (BQuarterEnd(1, startingMonth=3), datetime(2008, 2, 29), False),
  2627. (BQuarterEnd(1, startingMonth=3), datetime(2007, 3, 30), True),
  2628. (BQuarterEnd(1, startingMonth=3), datetime(2007, 3, 31), False),
  2629. (BQuarterEnd(1, startingMonth=3), datetime(2008, 4, 30), False),
  2630. (BQuarterEnd(1, startingMonth=3), datetime(2008, 5, 30), False),
  2631. (BQuarterEnd(1, startingMonth=3), datetime(2007, 6, 29), True),
  2632. (BQuarterEnd(1, startingMonth=3), datetime(2007, 6, 30), False),
  2633. ]
  2634. for offset, dt, expected in tests:
  2635. assertOnOffset(offset, dt, expected)
  2636. def makeFY5253LastOfMonthQuarter(*args, **kwds):
  2637. return FY5253Quarter(*args, variation="last", **kwds)
  2638. def makeFY5253NearestEndMonthQuarter(*args, **kwds):
  2639. return FY5253Quarter(*args, variation="nearest", **kwds)
  2640. def makeFY5253NearestEndMonth(*args, **kwds):
  2641. return FY5253(*args, variation="nearest", **kwds)
  2642. def makeFY5253LastOfMonth(*args, **kwds):
  2643. return FY5253(*args, variation="last", **kwds)
  2644. class TestFY5253LastOfMonth(Base):
  2645. def test_onOffset(self):
  2646. offset_lom_sat_aug = makeFY5253LastOfMonth(1, startingMonth=8,
  2647. weekday=WeekDay.SAT)
  2648. offset_lom_sat_sep = makeFY5253LastOfMonth(1, startingMonth=9,
  2649. weekday=WeekDay.SAT)
  2650. tests = [
  2651. # From Wikipedia (see:
  2652. # http://en.wikipedia.org/wiki/4%E2%80%934%E2%80%935_calendar#Last_Saturday_of_the_month_at_fiscal_year_end)
  2653. (offset_lom_sat_aug, datetime(2006, 8, 26), True),
  2654. (offset_lom_sat_aug, datetime(2007, 8, 25), True),
  2655. (offset_lom_sat_aug, datetime(2008, 8, 30), True),
  2656. (offset_lom_sat_aug, datetime(2009, 8, 29), True),
  2657. (offset_lom_sat_aug, datetime(2010, 8, 28), True),
  2658. (offset_lom_sat_aug, datetime(2011, 8, 27), True),
  2659. (offset_lom_sat_aug, datetime(2012, 8, 25), True),
  2660. (offset_lom_sat_aug, datetime(2013, 8, 31), True),
  2661. (offset_lom_sat_aug, datetime(2014, 8, 30), True),
  2662. (offset_lom_sat_aug, datetime(2015, 8, 29), True),
  2663. (offset_lom_sat_aug, datetime(2016, 8, 27), True),
  2664. (offset_lom_sat_aug, datetime(2017, 8, 26), True),
  2665. (offset_lom_sat_aug, datetime(2018, 8, 25), True),
  2666. (offset_lom_sat_aug, datetime(2019, 8, 31), True),
  2667. (offset_lom_sat_aug, datetime(2006, 8, 27), False),
  2668. (offset_lom_sat_aug, datetime(2007, 8, 28), False),
  2669. (offset_lom_sat_aug, datetime(2008, 8, 31), False),
  2670. (offset_lom_sat_aug, datetime(2009, 8, 30), False),
  2671. (offset_lom_sat_aug, datetime(2010, 8, 29), False),
  2672. (offset_lom_sat_aug, datetime(2011, 8, 28), False),
  2673. (offset_lom_sat_aug, datetime(2006, 8, 25), False),
  2674. (offset_lom_sat_aug, datetime(2007, 8, 24), False),
  2675. (offset_lom_sat_aug, datetime(2008, 8, 29), False),
  2676. (offset_lom_sat_aug, datetime(2009, 8, 28), False),
  2677. (offset_lom_sat_aug, datetime(2010, 8, 27), False),
  2678. (offset_lom_sat_aug, datetime(2011, 8, 26), False),
  2679. (offset_lom_sat_aug, datetime(2019, 8, 30), False),
  2680. # From GMCR (see for example:
  2681. # http://yahoo.brand.edgar-online.com/Default.aspx?
  2682. # companyid=3184&formtypeID=7)
  2683. (offset_lom_sat_sep, datetime(2010, 9, 25), True),
  2684. (offset_lom_sat_sep, datetime(2011, 9, 24), True),
  2685. (offset_lom_sat_sep, datetime(2012, 9, 29), True),
  2686. ]
  2687. for offset, dt, expected in tests:
  2688. assertOnOffset(offset, dt, expected)
  2689. def test_apply(self):
  2690. offset_lom_aug_sat = makeFY5253LastOfMonth(startingMonth=8,
  2691. weekday=WeekDay.SAT)
  2692. offset_lom_aug_sat_1 = makeFY5253LastOfMonth(n=1, startingMonth=8,
  2693. weekday=WeekDay.SAT)
  2694. date_seq_lom_aug_sat = [datetime(2006, 8, 26), datetime(2007, 8, 25),
  2695. datetime(2008, 8, 30), datetime(2009, 8, 29),
  2696. datetime(2010, 8, 28), datetime(2011, 8, 27),
  2697. datetime(2012, 8, 25), datetime(2013, 8, 31),
  2698. datetime(2014, 8, 30), datetime(2015, 8, 29),
  2699. datetime(2016, 8, 27)]
  2700. tests = [
  2701. (offset_lom_aug_sat, date_seq_lom_aug_sat),
  2702. (offset_lom_aug_sat_1, date_seq_lom_aug_sat),
  2703. (offset_lom_aug_sat, [
  2704. datetime(2006, 8, 25)] + date_seq_lom_aug_sat),
  2705. (offset_lom_aug_sat_1, [
  2706. datetime(2006, 8, 27)] + date_seq_lom_aug_sat[1:]),
  2707. (makeFY5253LastOfMonth(n=-1, startingMonth=8,
  2708. weekday=WeekDay.SAT),
  2709. list(reversed(date_seq_lom_aug_sat))),
  2710. ]
  2711. for test in tests:
  2712. offset, data = test
  2713. current = data[0]
  2714. for datum in data[1:]:
  2715. current = current + offset
  2716. self.assertEqual(current, datum)
  2717. class TestFY5253NearestEndMonth(Base):
  2718. def test_get_target_month_end(self):
  2719. self.assertEqual(makeFY5253NearestEndMonth(startingMonth=8,
  2720. weekday=WeekDay.SAT)
  2721. .get_target_month_end(
  2722. datetime(2013, 1, 1)), datetime(2013, 8, 31))
  2723. self.assertEqual(makeFY5253NearestEndMonth(startingMonth=12,
  2724. weekday=WeekDay.SAT)
  2725. .get_target_month_end(datetime(2013, 1, 1)),
  2726. datetime(2013, 12, 31))
  2727. self.assertEqual(makeFY5253NearestEndMonth(startingMonth=2,
  2728. weekday=WeekDay.SAT)
  2729. .get_target_month_end(datetime(2013, 1, 1)),
  2730. datetime(2013, 2, 28))
  2731. def test_get_year_end(self):
  2732. self.assertEqual(makeFY5253NearestEndMonth(startingMonth=8,
  2733. weekday=WeekDay.SAT)
  2734. .get_year_end(datetime(2013, 1, 1)),
  2735. datetime(2013, 8, 31))
  2736. self.assertEqual(makeFY5253NearestEndMonth(startingMonth=8,
  2737. weekday=WeekDay.SUN)
  2738. .get_year_end(datetime(2013, 1, 1)),
  2739. datetime(2013, 9, 1))
  2740. self.assertEqual(makeFY5253NearestEndMonth(startingMonth=8,
  2741. weekday=WeekDay.FRI)
  2742. .get_year_end(datetime(2013, 1, 1)),
  2743. datetime(2013, 8, 30))
  2744. offset_n = FY5253(weekday=WeekDay.TUE, startingMonth=12,
  2745. variation="nearest")
  2746. self.assertEqual(offset_n.get_year_end(
  2747. datetime(2012, 1, 1)), datetime(2013, 1, 1))
  2748. self.assertEqual(offset_n.get_year_end(
  2749. datetime(2012, 1, 10)), datetime(2013, 1, 1))
  2750. self.assertEqual(offset_n.get_year_end(
  2751. datetime(2013, 1, 1)), datetime(2013, 12, 31))
  2752. self.assertEqual(offset_n.get_year_end(
  2753. datetime(2013, 1, 2)), datetime(2013, 12, 31))
  2754. self.assertEqual(offset_n.get_year_end(
  2755. datetime(2013, 1, 3)), datetime(2013, 12, 31))
  2756. self.assertEqual(offset_n.get_year_end(
  2757. datetime(2013, 1, 10)), datetime(2013, 12, 31))
  2758. JNJ = FY5253(n=1, startingMonth=12, weekday=6, variation="nearest")
  2759. self.assertEqual(JNJ.get_year_end(
  2760. datetime(2006, 1, 1)), datetime(2006, 12, 31))
  2761. def test_onOffset(self):
  2762. offset_lom_aug_sat = makeFY5253NearestEndMonth(1, startingMonth=8,
  2763. weekday=WeekDay.SAT)
  2764. offset_lom_aug_thu = makeFY5253NearestEndMonth(1, startingMonth=8,
  2765. weekday=WeekDay.THU)
  2766. offset_n = FY5253(weekday=WeekDay.TUE, startingMonth=12,
  2767. variation="nearest")
  2768. tests = [
  2769. # From Wikipedia (see:
  2770. # http://en.wikipedia.org/wiki/4%E2%80%934%E2%80%935_calendar
  2771. # #Saturday_nearest_the_end_of_month)
  2772. # 2006-09-02 2006 September 2
  2773. # 2007-09-01 2007 September 1
  2774. # 2008-08-30 2008 August 30 (leap year)
  2775. # 2009-08-29 2009 August 29
  2776. # 2010-08-28 2010 August 28
  2777. # 2011-09-03 2011 September 3
  2778. # 2012-09-01 2012 September 1 (leap year)
  2779. # 2013-08-31 2013 August 31
  2780. # 2014-08-30 2014 August 30
  2781. # 2015-08-29 2015 August 29
  2782. # 2016-09-03 2016 September 3 (leap year)
  2783. # 2017-09-02 2017 September 2
  2784. # 2018-09-01 2018 September 1
  2785. # 2019-08-31 2019 August 31
  2786. (offset_lom_aug_sat, datetime(2006, 9, 2), True),
  2787. (offset_lom_aug_sat, datetime(2007, 9, 1), True),
  2788. (offset_lom_aug_sat, datetime(2008, 8, 30), True),
  2789. (offset_lom_aug_sat, datetime(2009, 8, 29), True),
  2790. (offset_lom_aug_sat, datetime(2010, 8, 28), True),
  2791. (offset_lom_aug_sat, datetime(2011, 9, 3), True),
  2792. (offset_lom_aug_sat, datetime(2016, 9, 3), True),
  2793. (offset_lom_aug_sat, datetime(2017, 9, 2), True),
  2794. (offset_lom_aug_sat, datetime(2018, 9, 1), True),
  2795. (offset_lom_aug_sat, datetime(2019, 8, 31), True),
  2796. (offset_lom_aug_sat, datetime(2006, 8, 27), False),
  2797. (offset_lom_aug_sat, datetime(2007, 8, 28), False),
  2798. (offset_lom_aug_sat, datetime(2008, 8, 31), False),
  2799. (offset_lom_aug_sat, datetime(2009, 8, 30), False),
  2800. (offset_lom_aug_sat, datetime(2010, 8, 29), False),
  2801. (offset_lom_aug_sat, datetime(2011, 8, 28), False),
  2802. (offset_lom_aug_sat, datetime(2006, 8, 25), False),
  2803. (offset_lom_aug_sat, datetime(2007, 8, 24), False),
  2804. (offset_lom_aug_sat, datetime(2008, 8, 29), False),
  2805. (offset_lom_aug_sat, datetime(2009, 8, 28), False),
  2806. (offset_lom_aug_sat, datetime(2010, 8, 27), False),
  2807. (offset_lom_aug_sat, datetime(2011, 8, 26), False),
  2808. (offset_lom_aug_sat, datetime(2019, 8, 30), False),
  2809. # From Micron, see:
  2810. # http://google.brand.edgar-online.com/?sym=MU&formtypeID=7
  2811. (offset_lom_aug_thu, datetime(2012, 8, 30), True),
  2812. (offset_lom_aug_thu, datetime(2011, 9, 1), True),
  2813. (offset_n, datetime(2012, 12, 31), False),
  2814. (offset_n, datetime(2013, 1, 1), True),
  2815. (offset_n, datetime(2013, 1, 2), False),
  2816. ]
  2817. for offset, dt, expected in tests:
  2818. assertOnOffset(offset, dt, expected)
  2819. def test_apply(self):
  2820. date_seq_nem_8_sat = [datetime(2006, 9, 2), datetime(2007, 9, 1),
  2821. datetime(2008, 8, 30), datetime(2009, 8, 29),
  2822. datetime(2010, 8, 28), datetime(2011, 9, 3)]
  2823. JNJ = [datetime(2005, 1, 2), datetime(2006, 1, 1),
  2824. datetime(2006, 12, 31), datetime(2007, 12, 30),
  2825. datetime(2008, 12, 28), datetime(2010, 1, 3),
  2826. datetime(2011, 1, 2), datetime(2012, 1, 1),
  2827. datetime(2012, 12, 30)]
  2828. DEC_SAT = FY5253(n=-1, startingMonth=12, weekday=5,
  2829. variation="nearest")
  2830. tests = [
  2831. (makeFY5253NearestEndMonth(startingMonth=8,
  2832. weekday=WeekDay.SAT),
  2833. date_seq_nem_8_sat),
  2834. (makeFY5253NearestEndMonth(n=1, startingMonth=8,
  2835. weekday=WeekDay.SAT),
  2836. date_seq_nem_8_sat),
  2837. (makeFY5253NearestEndMonth(startingMonth=8, weekday=WeekDay.SAT),
  2838. [datetime(2006, 9, 1)] + date_seq_nem_8_sat),
  2839. (makeFY5253NearestEndMonth(n=1, startingMonth=8,
  2840. weekday=WeekDay.SAT),
  2841. [datetime(2006, 9, 3)] + date_seq_nem_8_sat[1:]),
  2842. (makeFY5253NearestEndMonth(n=-1, startingMonth=8,
  2843. weekday=WeekDay.SAT),
  2844. list(reversed(date_seq_nem_8_sat))),
  2845. (makeFY5253NearestEndMonth(n=1, startingMonth=12,
  2846. weekday=WeekDay.SUN), JNJ),
  2847. (makeFY5253NearestEndMonth(n=-1, startingMonth=12,
  2848. weekday=WeekDay.SUN),
  2849. list(reversed(JNJ))),
  2850. (makeFY5253NearestEndMonth(n=1, startingMonth=12,
  2851. weekday=WeekDay.SUN),
  2852. [datetime(2005, 1, 2), datetime(2006, 1, 1)]),
  2853. (makeFY5253NearestEndMonth(n=1, startingMonth=12,
  2854. weekday=WeekDay.SUN),
  2855. [datetime(2006, 1, 2), datetime(2006, 12, 31)]),
  2856. (DEC_SAT, [datetime(2013, 1, 15), datetime(2012, 12, 29)])
  2857. ]
  2858. for test in tests:
  2859. offset, data = test
  2860. current = data[0]
  2861. for datum in data[1:]:
  2862. current = current + offset
  2863. self.assertEqual(current, datum)
  2864. class TestFY5253LastOfMonthQuarter(Base):
  2865. def test_isAnchored(self):
  2866. self.assertTrue(
  2867. makeFY5253LastOfMonthQuarter(startingMonth=1, weekday=WeekDay.SAT,
  2868. qtr_with_extra_week=4).isAnchored())
  2869. self.assertTrue(
  2870. makeFY5253LastOfMonthQuarter(weekday=WeekDay.SAT, startingMonth=3,
  2871. qtr_with_extra_week=4).isAnchored())
  2872. self.assertFalse(makeFY5253LastOfMonthQuarter(
  2873. 2, startingMonth=1, weekday=WeekDay.SAT,
  2874. qtr_with_extra_week=4).isAnchored())
  2875. def test_equality(self):
  2876. self.assertEqual(makeFY5253LastOfMonthQuarter(startingMonth=1,
  2877. weekday=WeekDay.SAT,
  2878. qtr_with_extra_week=4),
  2879. makeFY5253LastOfMonthQuarter(startingMonth=1,
  2880. weekday=WeekDay.SAT,
  2881. qtr_with_extra_week=4))
  2882. self.assertNotEqual(
  2883. makeFY5253LastOfMonthQuarter(
  2884. startingMonth=1, weekday=WeekDay.SAT,
  2885. qtr_with_extra_week=4),
  2886. makeFY5253LastOfMonthQuarter(
  2887. startingMonth=1, weekday=WeekDay.SUN,
  2888. qtr_with_extra_week=4))
  2889. self.assertNotEqual(
  2890. makeFY5253LastOfMonthQuarter(
  2891. startingMonth=1, weekday=WeekDay.SAT,
  2892. qtr_with_extra_week=4),
  2893. makeFY5253LastOfMonthQuarter(
  2894. startingMonth=2, weekday=WeekDay.SAT,
  2895. qtr_with_extra_week=4))
  2896. def test_offset(self):
  2897. offset = makeFY5253LastOfMonthQuarter(1, startingMonth=9,
  2898. weekday=WeekDay.SAT,
  2899. qtr_with_extra_week=4)
  2900. offset2 = makeFY5253LastOfMonthQuarter(2, startingMonth=9,
  2901. weekday=WeekDay.SAT,
  2902. qtr_with_extra_week=4)
  2903. offset4 = makeFY5253LastOfMonthQuarter(4, startingMonth=9,
  2904. weekday=WeekDay.SAT,
  2905. qtr_with_extra_week=4)
  2906. offset_neg1 = makeFY5253LastOfMonthQuarter(-1, startingMonth=9,
  2907. weekday=WeekDay.SAT,
  2908. qtr_with_extra_week=4)
  2909. offset_neg2 = makeFY5253LastOfMonthQuarter(-2, startingMonth=9,
  2910. weekday=WeekDay.SAT,
  2911. qtr_with_extra_week=4)
  2912. GMCR = [datetime(2010, 3, 27), datetime(2010, 6, 26),
  2913. datetime(2010, 9, 25), datetime(2010, 12, 25),
  2914. datetime(2011, 3, 26), datetime(2011, 6, 25),
  2915. datetime(2011, 9, 24), datetime(2011, 12, 24),
  2916. datetime(2012, 3, 24), datetime(2012, 6, 23),
  2917. datetime(2012, 9, 29), datetime(2012, 12, 29),
  2918. datetime(2013, 3, 30), datetime(2013, 6, 29)]
  2919. assertEq(offset, base=GMCR[0], expected=GMCR[1])
  2920. assertEq(offset, base=GMCR[0] + relativedelta(days=-1),
  2921. expected=GMCR[0])
  2922. assertEq(offset, base=GMCR[1], expected=GMCR[2])
  2923. assertEq(offset2, base=GMCR[0], expected=GMCR[2])
  2924. assertEq(offset4, base=GMCR[0], expected=GMCR[4])
  2925. assertEq(offset_neg1, base=GMCR[-1], expected=GMCR[-2])
  2926. assertEq(offset_neg1, base=GMCR[-1] + relativedelta(days=+1),
  2927. expected=GMCR[-1])
  2928. assertEq(offset_neg2, base=GMCR[-1], expected=GMCR[-3])
  2929. date = GMCR[0] + relativedelta(days=-1)
  2930. for expected in GMCR:
  2931. assertEq(offset, date, expected)
  2932. date = date + offset
  2933. date = GMCR[-1] + relativedelta(days=+1)
  2934. for expected in reversed(GMCR):
  2935. assertEq(offset_neg1, date, expected)
  2936. date = date + offset_neg1
  2937. def test_onOffset(self):
  2938. lomq_aug_sat_4 = makeFY5253LastOfMonthQuarter(1, startingMonth=8,
  2939. weekday=WeekDay.SAT,
  2940. qtr_with_extra_week=4)
  2941. lomq_sep_sat_4 = makeFY5253LastOfMonthQuarter(1, startingMonth=9,
  2942. weekday=WeekDay.SAT,
  2943. qtr_with_extra_week=4)
  2944. tests = [
  2945. # From Wikipedia
  2946. (lomq_aug_sat_4, datetime(2006, 8, 26), True),
  2947. (lomq_aug_sat_4, datetime(2007, 8, 25), True),
  2948. (lomq_aug_sat_4, datetime(2008, 8, 30), True),
  2949. (lomq_aug_sat_4, datetime(2009, 8, 29), True),
  2950. (lomq_aug_sat_4, datetime(2010, 8, 28), True),
  2951. (lomq_aug_sat_4, datetime(2011, 8, 27), True),
  2952. (lomq_aug_sat_4, datetime(2019, 8, 31), True),
  2953. (lomq_aug_sat_4, datetime(2006, 8, 27), False),
  2954. (lomq_aug_sat_4, datetime(2007, 8, 28), False),
  2955. (lomq_aug_sat_4, datetime(2008, 8, 31), False),
  2956. (lomq_aug_sat_4, datetime(2009, 8, 30), False),
  2957. (lomq_aug_sat_4, datetime(2010, 8, 29), False),
  2958. (lomq_aug_sat_4, datetime(2011, 8, 28), False),
  2959. (lomq_aug_sat_4, datetime(2006, 8, 25), False),
  2960. (lomq_aug_sat_4, datetime(2007, 8, 24), False),
  2961. (lomq_aug_sat_4, datetime(2008, 8, 29), False),
  2962. (lomq_aug_sat_4, datetime(2009, 8, 28), False),
  2963. (lomq_aug_sat_4, datetime(2010, 8, 27), False),
  2964. (lomq_aug_sat_4, datetime(2011, 8, 26), False),
  2965. (lomq_aug_sat_4, datetime(2019, 8, 30), False),
  2966. # From GMCR
  2967. (lomq_sep_sat_4, datetime(2010, 9, 25), True),
  2968. (lomq_sep_sat_4, datetime(2011, 9, 24), True),
  2969. (lomq_sep_sat_4, datetime(2012, 9, 29), True),
  2970. (lomq_sep_sat_4, datetime(2013, 6, 29), True),
  2971. (lomq_sep_sat_4, datetime(2012, 6, 23), True),
  2972. (lomq_sep_sat_4, datetime(2012, 6, 30), False),
  2973. (lomq_sep_sat_4, datetime(2013, 3, 30), True),
  2974. (lomq_sep_sat_4, datetime(2012, 3, 24), True),
  2975. (lomq_sep_sat_4, datetime(2012, 12, 29), True),
  2976. (lomq_sep_sat_4, datetime(2011, 12, 24), True),
  2977. # INTC (extra week in Q1)
  2978. # See: http://www.intc.com/releasedetail.cfm?ReleaseID=542844
  2979. (makeFY5253LastOfMonthQuarter(1, startingMonth=12,
  2980. weekday=WeekDay.SAT,
  2981. qtr_with_extra_week=1),
  2982. datetime(2011, 4, 2), True),
  2983. # see: http://google.brand.edgar-online.com/?sym=INTC&formtypeID=7
  2984. (makeFY5253LastOfMonthQuarter(1, startingMonth=12,
  2985. weekday=WeekDay.SAT,
  2986. qtr_with_extra_week=1),
  2987. datetime(2012, 12, 29), True),
  2988. (makeFY5253LastOfMonthQuarter(1, startingMonth=12,
  2989. weekday=WeekDay.SAT,
  2990. qtr_with_extra_week=1),
  2991. datetime(2011, 12, 31), True),
  2992. (makeFY5253LastOfMonthQuarter(1, startingMonth=12,
  2993. weekday=WeekDay.SAT,
  2994. qtr_with_extra_week=1),
  2995. datetime(2010, 12, 25), True),
  2996. ]
  2997. for offset, dt, expected in tests:
  2998. assertOnOffset(offset, dt, expected)
  2999. def test_year_has_extra_week(self):
  3000. # End of long Q1
  3001. self.assertTrue(
  3002. makeFY5253LastOfMonthQuarter(1, startingMonth=12,
  3003. weekday=WeekDay.SAT,
  3004. qtr_with_extra_week=1)
  3005. .year_has_extra_week(datetime(2011, 4, 2)))
  3006. # Start of long Q1
  3007. self.assertTrue(
  3008. makeFY5253LastOfMonthQuarter(
  3009. 1, startingMonth=12, weekday=WeekDay.SAT,
  3010. qtr_with_extra_week=1)
  3011. .year_has_extra_week(datetime(2010, 12, 26)))
  3012. # End of year before year with long Q1
  3013. self.assertFalse(
  3014. makeFY5253LastOfMonthQuarter(
  3015. 1, startingMonth=12, weekday=WeekDay.SAT,
  3016. qtr_with_extra_week=1)
  3017. .year_has_extra_week(datetime(2010, 12, 25)))
  3018. for year in [x
  3019. for x in range(1994, 2011 + 1)
  3020. if x not in [2011, 2005, 2000, 1994]]:
  3021. self.assertFalse(
  3022. makeFY5253LastOfMonthQuarter(
  3023. 1, startingMonth=12, weekday=WeekDay.SAT,
  3024. qtr_with_extra_week=1)
  3025. .year_has_extra_week(datetime(year, 4, 2)))
  3026. # Other long years
  3027. self.assertTrue(
  3028. makeFY5253LastOfMonthQuarter(
  3029. 1, startingMonth=12, weekday=WeekDay.SAT,
  3030. qtr_with_extra_week=1)
  3031. .year_has_extra_week(datetime(2005, 4, 2)))
  3032. self.assertTrue(
  3033. makeFY5253LastOfMonthQuarter(
  3034. 1, startingMonth=12, weekday=WeekDay.SAT,
  3035. qtr_with_extra_week=1)
  3036. .year_has_extra_week(datetime(2000, 4, 2)))
  3037. self.assertTrue(
  3038. makeFY5253LastOfMonthQuarter(
  3039. 1, startingMonth=12, weekday=WeekDay.SAT,
  3040. qtr_with_extra_week=1)
  3041. .year_has_extra_week(datetime(1994, 4, 2)))
  3042. def test_get_weeks(self):
  3043. sat_dec_1 = makeFY5253LastOfMonthQuarter(1, startingMonth=12,
  3044. weekday=WeekDay.SAT,
  3045. qtr_with_extra_week=1)
  3046. sat_dec_4 = makeFY5253LastOfMonthQuarter(1, startingMonth=12,
  3047. weekday=WeekDay.SAT,
  3048. qtr_with_extra_week=4)
  3049. self.assertEqual(sat_dec_1.get_weeks(
  3050. datetime(2011, 4, 2)), [14, 13, 13, 13])
  3051. self.assertEqual(sat_dec_4.get_weeks(
  3052. datetime(2011, 4, 2)), [13, 13, 13, 14])
  3053. self.assertEqual(sat_dec_1.get_weeks(
  3054. datetime(2010, 12, 25)), [13, 13, 13, 13])
  3055. class TestFY5253NearestEndMonthQuarter(Base):
  3056. def test_onOffset(self):
  3057. offset_nem_sat_aug_4 = makeFY5253NearestEndMonthQuarter(
  3058. 1, startingMonth=8, weekday=WeekDay.SAT,
  3059. qtr_with_extra_week=4)
  3060. offset_nem_thu_aug_4 = makeFY5253NearestEndMonthQuarter(
  3061. 1, startingMonth=8, weekday=WeekDay.THU,
  3062. qtr_with_extra_week=4)
  3063. offset_n = FY5253(weekday=WeekDay.TUE, startingMonth=12,
  3064. variation="nearest", qtr_with_extra_week=4)
  3065. tests = [
  3066. # From Wikipedia
  3067. (offset_nem_sat_aug_4, datetime(2006, 9, 2), True),
  3068. (offset_nem_sat_aug_4, datetime(2007, 9, 1), True),
  3069. (offset_nem_sat_aug_4, datetime(2008, 8, 30), True),
  3070. (offset_nem_sat_aug_4, datetime(2009, 8, 29), True),
  3071. (offset_nem_sat_aug_4, datetime(2010, 8, 28), True),
  3072. (offset_nem_sat_aug_4, datetime(2011, 9, 3), True),
  3073. (offset_nem_sat_aug_4, datetime(2016, 9, 3), True),
  3074. (offset_nem_sat_aug_4, datetime(2017, 9, 2), True),
  3075. (offset_nem_sat_aug_4, datetime(2018, 9, 1), True),
  3076. (offset_nem_sat_aug_4, datetime(2019, 8, 31), True),
  3077. (offset_nem_sat_aug_4, datetime(2006, 8, 27), False),
  3078. (offset_nem_sat_aug_4, datetime(2007, 8, 28), False),
  3079. (offset_nem_sat_aug_4, datetime(2008, 8, 31), False),
  3080. (offset_nem_sat_aug_4, datetime(2009, 8, 30), False),
  3081. (offset_nem_sat_aug_4, datetime(2010, 8, 29), False),
  3082. (offset_nem_sat_aug_4, datetime(2011, 8, 28), False),
  3083. (offset_nem_sat_aug_4, datetime(2006, 8, 25), False),
  3084. (offset_nem_sat_aug_4, datetime(2007, 8, 24), False),
  3085. (offset_nem_sat_aug_4, datetime(2008, 8, 29), False),
  3086. (offset_nem_sat_aug_4, datetime(2009, 8, 28), False),
  3087. (offset_nem_sat_aug_4, datetime(2010, 8, 27), False),
  3088. (offset_nem_sat_aug_4, datetime(2011, 8, 26), False),
  3089. (offset_nem_sat_aug_4, datetime(2019, 8, 30), False),
  3090. # From Micron, see:
  3091. # http://google.brand.edgar-online.com/?sym=MU&formtypeID=7
  3092. (offset_nem_thu_aug_4, datetime(2012, 8, 30), True),
  3093. (offset_nem_thu_aug_4, datetime(2011, 9, 1), True),
  3094. # See: http://google.brand.edgar-online.com/?sym=MU&formtypeID=13
  3095. (offset_nem_thu_aug_4, datetime(2013, 5, 30), True),
  3096. (offset_nem_thu_aug_4, datetime(2013, 2, 28), True),
  3097. (offset_nem_thu_aug_4, datetime(2012, 11, 29), True),
  3098. (offset_nem_thu_aug_4, datetime(2012, 5, 31), True),
  3099. (offset_nem_thu_aug_4, datetime(2007, 3, 1), True),
  3100. (offset_nem_thu_aug_4, datetime(1994, 3, 3), True),
  3101. (offset_n, datetime(2012, 12, 31), False),
  3102. (offset_n, datetime(2013, 1, 1), True),
  3103. (offset_n, datetime(2013, 1, 2), False)
  3104. ]
  3105. for offset, dt, expected in tests:
  3106. assertOnOffset(offset, dt, expected)
  3107. def test_offset(self):
  3108. offset = makeFY5253NearestEndMonthQuarter(1, startingMonth=8,
  3109. weekday=WeekDay.THU,
  3110. qtr_with_extra_week=4)
  3111. MU = [datetime(2012, 5, 31), datetime(2012, 8, 30), datetime(2012, 11,
  3112. 29),
  3113. datetime(2013, 2, 28), datetime(2013, 5, 30)]
  3114. date = MU[0] + relativedelta(days=-1)
  3115. for expected in MU:
  3116. assertEq(offset, date, expected)
  3117. date = date + offset
  3118. assertEq(offset, datetime(2012, 5, 31), datetime(2012, 8, 30))
  3119. assertEq(offset, datetime(2012, 5, 30), datetime(2012, 5, 31))
  3120. offset2 = FY5253Quarter(weekday=5, startingMonth=12, variation="last",
  3121. qtr_with_extra_week=4)
  3122. assertEq(offset2, datetime(2013, 1, 15), datetime(2013, 3, 30))
  3123. class TestQuarterBegin(Base):
  3124. def test_repr(self):
  3125. self.assertEqual(repr(QuarterBegin()),
  3126. "<QuarterBegin: startingMonth=3>")
  3127. self.assertEqual(repr(QuarterBegin(startingMonth=3)),
  3128. "<QuarterBegin: startingMonth=3>")
  3129. self.assertEqual(repr(QuarterBegin(startingMonth=1)),
  3130. "<QuarterBegin: startingMonth=1>")
  3131. def test_isAnchored(self):
  3132. self.assertTrue(QuarterBegin(startingMonth=1).isAnchored())
  3133. self.assertTrue(QuarterBegin().isAnchored())
  3134. self.assertFalse(QuarterBegin(2, startingMonth=1).isAnchored())
  3135. def test_offset(self):
  3136. tests = []
  3137. tests.append((QuarterBegin(startingMonth=1),
  3138. {datetime(2007, 12, 1): datetime(2008, 1, 1),
  3139. datetime(2008, 1, 1): datetime(2008, 4, 1),
  3140. datetime(2008, 2, 15): datetime(2008, 4, 1),
  3141. datetime(2008, 2, 29): datetime(2008, 4, 1),
  3142. datetime(2008, 3, 15): datetime(2008, 4, 1),
  3143. datetime(2008, 3, 31): datetime(2008, 4, 1),
  3144. datetime(2008, 4, 15): datetime(2008, 7, 1),
  3145. datetime(2008, 4, 1): datetime(2008, 7, 1), }))
  3146. tests.append((QuarterBegin(startingMonth=2),
  3147. {datetime(2008, 1, 1): datetime(2008, 2, 1),
  3148. datetime(2008, 1, 31): datetime(2008, 2, 1),
  3149. datetime(2008, 1, 15): datetime(2008, 2, 1),
  3150. datetime(2008, 2, 29): datetime(2008, 5, 1),
  3151. datetime(2008, 3, 15): datetime(2008, 5, 1),
  3152. datetime(2008, 3, 31): datetime(2008, 5, 1),
  3153. datetime(2008, 4, 15): datetime(2008, 5, 1),
  3154. datetime(2008, 4, 30): datetime(2008, 5, 1), }))
  3155. tests.append((QuarterBegin(startingMonth=1, n=0),
  3156. {datetime(2008, 1, 1): datetime(2008, 1, 1),
  3157. datetime(2008, 12, 1): datetime(2009, 1, 1),
  3158. datetime(2008, 1, 1): datetime(2008, 1, 1),
  3159. datetime(2008, 2, 15): datetime(2008, 4, 1),
  3160. datetime(2008, 2, 29): datetime(2008, 4, 1),
  3161. datetime(2008, 3, 15): datetime(2008, 4, 1),
  3162. datetime(2008, 3, 31): datetime(2008, 4, 1),
  3163. datetime(2008, 4, 15): datetime(2008, 7, 1),
  3164. datetime(2008, 4, 30): datetime(2008, 7, 1), }))
  3165. tests.append((QuarterBegin(startingMonth=1, n=-1),
  3166. {datetime(2008, 1, 1): datetime(2007, 10, 1),
  3167. datetime(2008, 1, 31): datetime(2008, 1, 1),
  3168. datetime(2008, 2, 15): datetime(2008, 1, 1),
  3169. datetime(2008, 2, 29): datetime(2008, 1, 1),
  3170. datetime(2008, 3, 15): datetime(2008, 1, 1),
  3171. datetime(2008, 3, 31): datetime(2008, 1, 1),
  3172. datetime(2008, 4, 15): datetime(2008, 4, 1),
  3173. datetime(2008, 4, 30): datetime(2008, 4, 1),
  3174. datetime(2008, 7, 1): datetime(2008, 4, 1)}))
  3175. tests.append((QuarterBegin(startingMonth=1, n=2),
  3176. {datetime(2008, 1, 1): datetime(2008, 7, 1),
  3177. datetime(2008, 2, 15): datetime(2008, 7, 1),
  3178. datetime(2008, 2, 29): datetime(2008, 7, 1),
  3179. datetime(2008, 3, 15): datetime(2008, 7, 1),
  3180. datetime(2008, 3, 31): datetime(2008, 7, 1),
  3181. datetime(2008, 4, 15): datetime(2008, 10, 1),
  3182. datetime(2008, 4, 1): datetime(2008, 10, 1), }))
  3183. for offset, cases in tests:
  3184. for base, expected in compat.iteritems(cases):
  3185. assertEq(offset, base, expected)
  3186. # corner
  3187. offset = QuarterBegin(n=-1, startingMonth=1)
  3188. self.assertEqual(datetime(2010, 2, 1) + offset, datetime(2010, 1, 1))
  3189. class TestQuarterEnd(Base):
  3190. _offset = QuarterEnd
  3191. def test_repr(self):
  3192. self.assertEqual(repr(QuarterEnd()), "<QuarterEnd: startingMonth=3>")
  3193. self.assertEqual(repr(QuarterEnd(startingMonth=3)),
  3194. "<QuarterEnd: startingMonth=3>")
  3195. self.assertEqual(repr(QuarterEnd(startingMonth=1)),
  3196. "<QuarterEnd: startingMonth=1>")
  3197. def test_isAnchored(self):
  3198. self.assertTrue(QuarterEnd(startingMonth=1).isAnchored())
  3199. self.assertTrue(QuarterEnd().isAnchored())
  3200. self.assertFalse(QuarterEnd(2, startingMonth=1).isAnchored())
  3201. def test_offset(self):
  3202. tests = []
  3203. tests.append((QuarterEnd(startingMonth=1),
  3204. {datetime(2008, 1, 1): datetime(2008, 1, 31),
  3205. datetime(2008, 1, 31): datetime(2008, 4, 30),
  3206. datetime(2008, 2, 15): datetime(2008, 4, 30),
  3207. datetime(2008, 2, 29): datetime(2008, 4, 30),
  3208. datetime(2008, 3, 15): datetime(2008, 4, 30),
  3209. datetime(2008, 3, 31): datetime(2008, 4, 30),
  3210. datetime(2008, 4, 15): datetime(2008, 4, 30),
  3211. datetime(2008, 4, 30): datetime(2008, 7, 31), }))
  3212. tests.append((QuarterEnd(startingMonth=2),
  3213. {datetime(2008, 1, 1): datetime(2008, 2, 29),
  3214. datetime(2008, 1, 31): datetime(2008, 2, 29),
  3215. datetime(2008, 2, 15): datetime(2008, 2, 29),
  3216. datetime(2008, 2, 29): datetime(2008, 5, 31),
  3217. datetime(2008, 3, 15): datetime(2008, 5, 31),
  3218. datetime(2008, 3, 31): datetime(2008, 5, 31),
  3219. datetime(2008, 4, 15): datetime(2008, 5, 31),
  3220. datetime(2008, 4, 30): datetime(2008, 5, 31), }))
  3221. tests.append((QuarterEnd(startingMonth=1, n=0),
  3222. {datetime(2008, 1, 1): datetime(2008, 1, 31),
  3223. datetime(2008, 1, 31): datetime(2008, 1, 31),
  3224. datetime(2008, 2, 15): datetime(2008, 4, 30),
  3225. datetime(2008, 2, 29): datetime(2008, 4, 30),
  3226. datetime(2008, 3, 15): datetime(2008, 4, 30),
  3227. datetime(2008, 3, 31): datetime(2008, 4, 30),
  3228. datetime(2008, 4, 15): datetime(2008, 4, 30),
  3229. datetime(2008, 4, 30): datetime(2008, 4, 30), }))
  3230. tests.append((QuarterEnd(startingMonth=1, n=-1),
  3231. {datetime(2008, 1, 1): datetime(2007, 10, 31),
  3232. datetime(2008, 1, 31): datetime(2007, 10, 31),
  3233. datetime(2008, 2, 15): datetime(2008, 1, 31),
  3234. datetime(2008, 2, 29): datetime(2008, 1, 31),
  3235. datetime(2008, 3, 15): datetime(2008, 1, 31),
  3236. datetime(2008, 3, 31): datetime(2008, 1, 31),
  3237. datetime(2008, 4, 15): datetime(2008, 1, 31),
  3238. datetime(2008, 4, 30): datetime(2008, 1, 31),
  3239. datetime(2008, 7, 1): datetime(2008, 4, 30)}))
  3240. tests.append((QuarterEnd(startingMonth=1, n=2),
  3241. {datetime(2008, 1, 31): datetime(2008, 7, 31),
  3242. datetime(2008, 2, 15): datetime(2008, 7, 31),
  3243. datetime(2008, 2, 29): datetime(2008, 7, 31),
  3244. datetime(2008, 3, 15): datetime(2008, 7, 31),
  3245. datetime(2008, 3, 31): datetime(2008, 7, 31),
  3246. datetime(2008, 4, 15): datetime(2008, 7, 31),
  3247. datetime(2008, 4, 30): datetime(2008, 10, 31), }))
  3248. for offset, cases in tests:
  3249. for base, expected in compat.iteritems(cases):
  3250. assertEq(offset, base, expected)
  3251. # corner
  3252. offset = QuarterEnd(n=-1, startingMonth=1)
  3253. self.assertEqual(datetime(2010, 2, 1) + offset, datetime(2010, 1, 31))
  3254. def test_onOffset(self):
  3255. tests = [(QuarterEnd(1, startingMonth=1), datetime(2008, 1, 31), True),
  3256. (QuarterEnd(1, startingMonth=1), datetime(2007, 12, 31),
  3257. False),
  3258. (QuarterEnd(1, startingMonth=1), datetime(2008, 2, 29),
  3259. False),
  3260. (QuarterEnd(1, startingMonth=1), datetime(2007, 3, 30),
  3261. False),
  3262. (QuarterEnd(1, startingMonth=1), datetime(2007, 3, 31),
  3263. False),
  3264. (QuarterEnd(1, startingMonth=1), datetime(2008, 4, 30), True),
  3265. (QuarterEnd(1, startingMonth=1), datetime(2008, 5, 30),
  3266. False),
  3267. (QuarterEnd(1, startingMonth=1), datetime(2008, 5, 31),
  3268. False),
  3269. (QuarterEnd(1, startingMonth=1), datetime(2007, 6, 29),
  3270. False),
  3271. (QuarterEnd(1, startingMonth=1), datetime(2007, 6, 30),
  3272. False),
  3273. (QuarterEnd(1, startingMonth=2), datetime(2008, 1, 31),
  3274. False),
  3275. (QuarterEnd(1, startingMonth=2), datetime(2007, 12, 31),
  3276. False),
  3277. (QuarterEnd(1, startingMonth=2), datetime(2008, 2, 29), True),
  3278. (QuarterEnd(1, startingMonth=2), datetime(2007, 3, 30),
  3279. False),
  3280. (QuarterEnd(1, startingMonth=2), datetime(2007, 3, 31),
  3281. False),
  3282. (QuarterEnd(1, startingMonth=2), datetime(2008, 4, 30),
  3283. False),
  3284. (QuarterEnd(1, startingMonth=2), datetime(2008, 5, 30),
  3285. False),
  3286. (QuarterEnd(1, startingMonth=2), datetime(2008, 5, 31), True),
  3287. (QuarterEnd(1, startingMonth=2), datetime(2007, 6, 29),
  3288. False),
  3289. (QuarterEnd(1, startingMonth=2), datetime(2007, 6, 30),
  3290. False),
  3291. (QuarterEnd(1, startingMonth=3), datetime(2008, 1, 31),
  3292. False),
  3293. (QuarterEnd(1, startingMonth=3), datetime(2007, 12, 31),
  3294. True),
  3295. (QuarterEnd(1, startingMonth=3), datetime(2008, 2, 29),
  3296. False),
  3297. (QuarterEnd(1, startingMonth=3), datetime(2007, 3, 30),
  3298. False),
  3299. (QuarterEnd(1, startingMonth=3), datetime(2007, 3, 31), True),
  3300. (QuarterEnd(1, startingMonth=3), datetime(2008, 4, 30),
  3301. False),
  3302. (QuarterEnd(1, startingMonth=3), datetime(2008, 5, 30),
  3303. False),
  3304. (QuarterEnd(1, startingMonth=3), datetime(2008, 5, 31),
  3305. False),
  3306. (QuarterEnd(1, startingMonth=3), datetime(2007, 6, 29),
  3307. False),
  3308. (QuarterEnd(1, startingMonth=3), datetime(2007, 6, 30),
  3309. True), ]
  3310. for offset, dt, expected in tests:
  3311. assertOnOffset(offset, dt, expected)
  3312. class TestBYearBegin(Base):
  3313. _offset = BYearBegin
  3314. def test_misspecified(self):
  3315. self.assertRaises(ValueError, BYearBegin, month=13)
  3316. self.assertRaises(ValueError, BYearEnd, month=13)
  3317. def test_offset(self):
  3318. tests = []
  3319. tests.append((BYearBegin(),
  3320. {datetime(2008, 1, 1): datetime(2009, 1, 1),
  3321. datetime(2008, 6, 30): datetime(2009, 1, 1),
  3322. datetime(2008, 12, 31): datetime(2009, 1, 1),
  3323. datetime(2011, 1, 1): datetime(2011, 1, 3),
  3324. datetime(2011, 1, 3): datetime(2012, 1, 2),
  3325. datetime(2005, 12, 30): datetime(2006, 1, 2),
  3326. datetime(2005, 12, 31): datetime(2006, 1, 2)}))
  3327. tests.append((BYearBegin(0),
  3328. {datetime(2008, 1, 1): datetime(2008, 1, 1),
  3329. datetime(2008, 6, 30): datetime(2009, 1, 1),
  3330. datetime(2008, 12, 31): datetime(2009, 1, 1),
  3331. datetime(2005, 12, 30): datetime(2006, 1, 2),
  3332. datetime(2005, 12, 31): datetime(2006, 1, 2), }))
  3333. tests.append((BYearBegin(-1),
  3334. {datetime(2007, 1, 1): datetime(2006, 1, 2),
  3335. datetime(2009, 1, 4): datetime(2009, 1, 1),
  3336. datetime(2009, 1, 1): datetime(2008, 1, 1),
  3337. datetime(2008, 6, 30): datetime(2008, 1, 1),
  3338. datetime(2008, 12, 31): datetime(2008, 1, 1),
  3339. datetime(2006, 12, 29): datetime(2006, 1, 2),
  3340. datetime(2006, 12, 30): datetime(2006, 1, 2),
  3341. datetime(2006, 1, 1): datetime(2005, 1, 3), }))
  3342. tests.append((BYearBegin(-2),
  3343. {datetime(2007, 1, 1): datetime(2005, 1, 3),
  3344. datetime(2007, 6, 30): datetime(2006, 1, 2),
  3345. datetime(2008, 12, 31): datetime(2007, 1, 1), }))
  3346. for offset, cases in tests:
  3347. for base, expected in compat.iteritems(cases):
  3348. assertEq(offset, base, expected)
  3349. class TestYearBegin(Base):
  3350. _offset = YearBegin
  3351. def test_misspecified(self):
  3352. self.assertRaises(ValueError, YearBegin, month=13)
  3353. def test_offset(self):
  3354. tests = []
  3355. tests.append((YearBegin(),
  3356. {datetime(2008, 1, 1): datetime(2009, 1, 1),
  3357. datetime(2008, 6, 30): datetime(2009, 1, 1),
  3358. datetime(2008, 12, 31): datetime(2009, 1, 1),
  3359. datetime(2005, 12, 30): datetime(2006, 1, 1),
  3360. datetime(2005, 12, 31): datetime(2006, 1, 1), }))
  3361. tests.append((YearBegin(0),
  3362. {datetime(2008, 1, 1): datetime(2008, 1, 1),
  3363. datetime(2008, 6, 30): datetime(2009, 1, 1),
  3364. datetime(2008, 12, 31): datetime(2009, 1, 1),
  3365. datetime(2005, 12, 30): datetime(2006, 1, 1),
  3366. datetime(2005, 12, 31): datetime(2006, 1, 1), }))
  3367. tests.append((YearBegin(3),
  3368. {datetime(2008, 1, 1): datetime(2011, 1, 1),
  3369. datetime(2008, 6, 30): datetime(2011, 1, 1),
  3370. datetime(2008, 12, 31): datetime(2011, 1, 1),
  3371. datetime(2005, 12, 30): datetime(2008, 1, 1),
  3372. datetime(2005, 12, 31): datetime(2008, 1, 1), }))
  3373. tests.append((YearBegin(-1),
  3374. {datetime(2007, 1, 1): datetime(2006, 1, 1),
  3375. datetime(2007, 1, 15): datetime(2007, 1, 1),
  3376. datetime(2008, 6, 30): datetime(2008, 1, 1),
  3377. datetime(2008, 12, 31): datetime(2008, 1, 1),
  3378. datetime(2006, 12, 29): datetime(2006, 1, 1),
  3379. datetime(2006, 12, 30): datetime(2006, 1, 1),
  3380. datetime(2007, 1, 1): datetime(2006, 1, 1), }))
  3381. tests.append((YearBegin(-2),
  3382. {datetime(2007, 1, 1): datetime(2005, 1, 1),
  3383. datetime(2008, 6, 30): datetime(2007, 1, 1),
  3384. datetime(2008, 12, 31): datetime(2007, 1, 1), }))
  3385. tests.append((YearBegin(month=4),
  3386. {datetime(2007, 4, 1): datetime(2008, 4, 1),
  3387. datetime(2007, 4, 15): datetime(2008, 4, 1),
  3388. datetime(2007, 3, 1): datetime(2007, 4, 1),
  3389. datetime(2007, 12, 15): datetime(2008, 4, 1),
  3390. datetime(2012, 1, 31): datetime(2012, 4, 1), }))
  3391. tests.append((YearBegin(0, month=4),
  3392. {datetime(2007, 4, 1): datetime(2007, 4, 1),
  3393. datetime(2007, 3, 1): datetime(2007, 4, 1),
  3394. datetime(2007, 12, 15): datetime(2008, 4, 1),
  3395. datetime(2012, 1, 31): datetime(2012, 4, 1), }))
  3396. tests.append((YearBegin(4, month=4),
  3397. {datetime(2007, 4, 1): datetime(2011, 4, 1),
  3398. datetime(2007, 4, 15): datetime(2011, 4, 1),
  3399. datetime(2007, 3, 1): datetime(2010, 4, 1),
  3400. datetime(2007, 12, 15): datetime(2011, 4, 1),
  3401. datetime(2012, 1, 31): datetime(2015, 4, 1), }))
  3402. tests.append((YearBegin(-1, month=4),
  3403. {datetime(2007, 4, 1): datetime(2006, 4, 1),
  3404. datetime(2007, 3, 1): datetime(2006, 4, 1),
  3405. datetime(2007, 12, 15): datetime(2007, 4, 1),
  3406. datetime(2012, 1, 31): datetime(2011, 4, 1), }))
  3407. tests.append((YearBegin(-3, month=4),
  3408. {datetime(2007, 4, 1): datetime(2004, 4, 1),
  3409. datetime(2007, 3, 1): datetime(2004, 4, 1),
  3410. datetime(2007, 12, 15): datetime(2005, 4, 1),
  3411. datetime(2012, 1, 31): datetime(2009, 4, 1), }))
  3412. for offset, cases in tests:
  3413. for base, expected in compat.iteritems(cases):
  3414. assertEq(offset, base, expected)
  3415. def test_onOffset(self):
  3416. tests = [
  3417. (YearBegin(), datetime(2007, 1, 3), False),
  3418. (YearBegin(), datetime(2008, 1, 1), True),
  3419. (YearBegin(), datetime(2006, 12, 31), False),
  3420. (YearBegin(), datetime(2006, 1, 2), False),
  3421. ]
  3422. for offset, dt, expected in tests:
  3423. assertOnOffset(offset, dt, expected)
  3424. class TestBYearEndLagged(Base):
  3425. def test_bad_month_fail(self):
  3426. self.assertRaises(Exception, BYearEnd, month=13)
  3427. self.assertRaises(Exception, BYearEnd, month=0)
  3428. def test_offset(self):
  3429. tests = []
  3430. tests.append((BYearEnd(month=6),
  3431. {datetime(2008, 1, 1): datetime(2008, 6, 30),
  3432. datetime(2007, 6, 30): datetime(2008, 6, 30)}, ))
  3433. tests.append((BYearEnd(n=-1, month=6),
  3434. {datetime(2008, 1, 1): datetime(2007, 6, 29),
  3435. datetime(2007, 6, 30): datetime(2007, 6, 29)}, ))
  3436. for offset, cases in tests:
  3437. for base, expected in compat.iteritems(cases):
  3438. self.assertEqual(base + offset, expected)
  3439. def test_roll(self):
  3440. offset = BYearEnd(month=6)
  3441. date = datetime(2009, 11, 30)
  3442. self.assertEqual(offset.rollforward(date), datetime(2010, 6, 30))
  3443. self.assertEqual(offset.rollback(date), datetime(2009, 6, 30))
  3444. def test_onOffset(self):
  3445. tests = [
  3446. (BYearEnd(month=2), datetime(2007, 2, 28), True),
  3447. (BYearEnd(month=6), datetime(2007, 6, 30), False),
  3448. ]
  3449. for offset, dt, expected in tests:
  3450. assertOnOffset(offset, dt, expected)
  3451. class TestBYearEnd(Base):
  3452. _offset = BYearEnd
  3453. def test_offset(self):
  3454. tests = []
  3455. tests.append((BYearEnd(),
  3456. {datetime(2008, 1, 1): datetime(2008, 12, 31),
  3457. datetime(2008, 6, 30): datetime(2008, 12, 31),
  3458. datetime(2008, 12, 31): datetime(2009, 12, 31),
  3459. datetime(2005, 12, 30): datetime(2006, 12, 29),
  3460. datetime(2005, 12, 31): datetime(2006, 12, 29), }))
  3461. tests.append((BYearEnd(0),
  3462. {datetime(2008, 1, 1): datetime(2008, 12, 31),
  3463. datetime(2008, 6, 30): datetime(2008, 12, 31),
  3464. datetime(2008, 12, 31): datetime(2008, 12, 31),
  3465. datetime(2005, 12, 31): datetime(2006, 12, 29), }))
  3466. tests.append((BYearEnd(-1),
  3467. {datetime(2007, 1, 1): datetime(2006, 12, 29),
  3468. datetime(2008, 6, 30): datetime(2007, 12, 31),
  3469. datetime(2008, 12, 31): datetime(2007, 12, 31),
  3470. datetime(2006, 12, 29): datetime(2005, 12, 30),
  3471. datetime(2006, 12, 30): datetime(2006, 12, 29),
  3472. datetime(2007, 1, 1): datetime(2006, 12, 29), }))
  3473. tests.append((BYearEnd(-2),
  3474. {datetime(2007, 1, 1): datetime(2005, 12, 30),
  3475. datetime(2008, 6, 30): datetime(2006, 12, 29),
  3476. datetime(2008, 12, 31): datetime(2006, 12, 29), }))
  3477. for offset, cases in tests:
  3478. for base, expected in compat.iteritems(cases):
  3479. assertEq(offset, base, expected)
  3480. def test_onOffset(self):
  3481. tests = [
  3482. (BYearEnd(), datetime(2007, 12, 31), True),
  3483. (BYearEnd(), datetime(2008, 1, 1), False),
  3484. (BYearEnd(), datetime(2006, 12, 31), False),
  3485. (BYearEnd(), datetime(2006, 12, 29), True),
  3486. ]
  3487. for offset, dt, expected in tests:
  3488. assertOnOffset(offset, dt, expected)
  3489. class TestYearEnd(Base):
  3490. _offset = YearEnd
  3491. def test_misspecified(self):
  3492. self.assertRaises(ValueError, YearEnd, month=13)
  3493. def test_offset(self):
  3494. tests = []
  3495. tests.append((YearEnd(),
  3496. {datetime(2008, 1, 1): datetime(2008, 12, 31),
  3497. datetime(2008, 6, 30): datetime(2008, 12, 31),
  3498. datetime(2008, 12, 31): datetime(2009, 12, 31),
  3499. datetime(2005, 12, 30): datetime(2005, 12, 31),
  3500. datetime(2005, 12, 31): datetime(2006, 12, 31), }))
  3501. tests.append((YearEnd(0),
  3502. {datetime(2008, 1, 1): datetime(2008, 12, 31),
  3503. datetime(2008, 6, 30): datetime(2008, 12, 31),
  3504. datetime(2008, 12, 31): datetime(2008, 12, 31),
  3505. datetime(2005, 12, 30): datetime(2005, 12, 31), }))
  3506. tests.append((YearEnd(-1),
  3507. {datetime(2007, 1, 1): datetime(2006, 12, 31),
  3508. datetime(2008, 6, 30): datetime(2007, 12, 31),
  3509. datetime(2008, 12, 31): datetime(2007, 12, 31),
  3510. datetime(2006, 12, 29): datetime(2005, 12, 31),
  3511. datetime(2006, 12, 30): datetime(2005, 12, 31),
  3512. datetime(2007, 1, 1): datetime(2006, 12, 31), }))
  3513. tests.append((YearEnd(-2),
  3514. {datetime(2007, 1, 1): datetime(2005, 12, 31),
  3515. datetime(2008, 6, 30): datetime(2006, 12, 31),
  3516. datetime(2008, 12, 31): datetime(2006, 12, 31), }))
  3517. for offset, cases in tests:
  3518. for base, expected in compat.iteritems(cases):
  3519. assertEq(offset, base, expected)
  3520. def test_onOffset(self):
  3521. tests = [
  3522. (YearEnd(), datetime(2007, 12, 31), True),
  3523. (YearEnd(), datetime(2008, 1, 1), False),
  3524. (YearEnd(), datetime(2006, 12, 31), True),
  3525. (YearEnd(), datetime(2006, 12, 29), False),
  3526. ]
  3527. for offset, dt, expected in tests:
  3528. assertOnOffset(offset, dt, expected)
  3529. class TestYearEndDiffMonth(Base):
  3530. def test_offset(self):
  3531. tests = []
  3532. tests.append((YearEnd(month=3),
  3533. {datetime(2008, 1, 1): datetime(2008, 3, 31),
  3534. datetime(2008, 2, 15): datetime(2008, 3, 31),
  3535. datetime(2008, 3, 31): datetime(2009, 3, 31),
  3536. datetime(2008, 3, 30): datetime(2008, 3, 31),
  3537. datetime(2005, 3, 31): datetime(2006, 3, 31),
  3538. datetime(2006, 7, 30): datetime(2007, 3, 31)}))
  3539. tests.append((YearEnd(0, month=3),
  3540. {datetime(2008, 1, 1): datetime(2008, 3, 31),
  3541. datetime(2008, 2, 28): datetime(2008, 3, 31),
  3542. datetime(2008, 3, 31): datetime(2008, 3, 31),
  3543. datetime(2005, 3, 30): datetime(2005, 3, 31), }))
  3544. tests.append((YearEnd(-1, month=3),
  3545. {datetime(2007, 1, 1): datetime(2006, 3, 31),
  3546. datetime(2008, 2, 28): datetime(2007, 3, 31),
  3547. datetime(2008, 3, 31): datetime(2007, 3, 31),
  3548. datetime(2006, 3, 29): datetime(2005, 3, 31),
  3549. datetime(2006, 3, 30): datetime(2005, 3, 31),
  3550. datetime(2007, 3, 1): datetime(2006, 3, 31), }))
  3551. tests.append((YearEnd(-2, month=3),
  3552. {datetime(2007, 1, 1): datetime(2005, 3, 31),
  3553. datetime(2008, 6, 30): datetime(2007, 3, 31),
  3554. datetime(2008, 3, 31): datetime(2006, 3, 31), }))
  3555. for offset, cases in tests:
  3556. for base, expected in compat.iteritems(cases):
  3557. assertEq(offset, base, expected)
  3558. def test_onOffset(self):
  3559. tests = [
  3560. (YearEnd(month=3), datetime(2007, 3, 31), True),
  3561. (YearEnd(month=3), datetime(2008, 1, 1), False),
  3562. (YearEnd(month=3), datetime(2006, 3, 31), True),
  3563. (YearEnd(month=3), datetime(2006, 3, 29), False),
  3564. ]
  3565. for offset, dt, expected in tests:
  3566. assertOnOffset(offset, dt, expected)
  3567. def assertEq(offset, base, expected):
  3568. actual = offset + base
  3569. actual_swapped = base + offset
  3570. actual_apply = offset.apply(base)
  3571. try:
  3572. assert actual == expected
  3573. assert actual_swapped == expected
  3574. assert actual_apply == expected
  3575. except AssertionError:
  3576. raise AssertionError("\nExpected: %s\nActual: %s\nFor Offset: %s)"
  3577. "\nAt Date: %s" %
  3578. (expected, actual, offset, base))
  3579. def test_Easter():
  3580. assertEq(Easter(), datetime(2010, 1, 1), datetime(2010, 4, 4))
  3581. assertEq(Easter(), datetime(2010, 4, 5), datetime(2011, 4, 24))
  3582. assertEq(Easter(2), datetime(2010, 1, 1), datetime(2011, 4, 24))
  3583. assertEq(Easter(), datetime(2010, 4, 4), datetime(2011, 4, 24))
  3584. assertEq(Easter(2), datetime(2010, 4, 4), datetime(2012, 4, 8))
  3585. assertEq(-Easter(), datetime(2011, 1, 1), datetime(2010, 4, 4))
  3586. assertEq(-Easter(), datetime(2010, 4, 5), datetime(2010, 4, 4))
  3587. assertEq(-Easter(2), datetime(2011, 1, 1), datetime(2009, 4, 12))
  3588. assertEq(-Easter(), datetime(2010, 4, 4), datetime(2009, 4, 12))
  3589. assertEq(-Easter(2), datetime(2010, 4, 4), datetime(2008, 3, 23))
  3590. class TestTicks(tm.TestCase):
  3591. ticks = [Hour, Minute, Second, Milli, Micro, Nano]
  3592. def test_ticks(self):
  3593. offsets = [(Hour, Timedelta(hours=5)),
  3594. (Minute, Timedelta(hours=2, minutes=3)),
  3595. (Second, Timedelta(hours=2, seconds=3)),
  3596. (Milli, Timedelta(hours=2, milliseconds=3)),
  3597. (Micro, Timedelta(hours=2, microseconds=3)),
  3598. (Nano, Timedelta(hours=2, nanoseconds=3))]
  3599. for kls, expected in offsets:
  3600. offset = kls(3)
  3601. result = offset + Timedelta(hours=2)
  3602. self.assertTrue(isinstance(result, Timedelta))
  3603. self.assertEqual(result, expected)
  3604. def test_Hour(self):
  3605. assertEq(Hour(), datetime(2010, 1, 1), datetime(2010, 1, 1, 1))
  3606. assertEq(Hour(-1), datetime(2010, 1, 1, 1), datetime(2010, 1, 1))
  3607. assertEq(2 * Hour(), datetime(2010, 1, 1), datetime(2010, 1, 1, 2))
  3608. assertEq(-1 * Hour(), datetime(2010, 1, 1, 1), datetime(2010, 1, 1))
  3609. self.assertEqual(Hour(3) + Hour(2), Hour(5))
  3610. self.assertEqual(Hour(3) - Hour(2), Hour())
  3611. self.assertNotEqual(Hour(4), Hour(1))
  3612. def test_Minute(self):
  3613. assertEq(Minute(), datetime(2010, 1, 1), datetime(2010, 1, 1, 0, 1))
  3614. assertEq(Minute(-1), datetime(2010, 1, 1, 0, 1), datetime(2010, 1, 1))
  3615. assertEq(2 * Minute(), datetime(2010, 1, 1),
  3616. datetime(2010, 1, 1, 0, 2))
  3617. assertEq(-1 * Minute(), datetime(2010, 1, 1, 0, 1),
  3618. datetime(2010, 1, 1))
  3619. self.assertEqual(Minute(3) + Minute(2), Minute(5))
  3620. self.assertEqual(Minute(3) - Minute(2), Minute())
  3621. self.assertNotEqual(Minute(5), Minute())
  3622. def test_Second(self):
  3623. assertEq(Second(), datetime(2010, 1, 1), datetime(2010, 1, 1, 0, 0, 1))
  3624. assertEq(Second(-1), datetime(2010, 1, 1,
  3625. 0, 0, 1), datetime(2010, 1, 1))
  3626. assertEq(2 * Second(), datetime(2010, 1, 1),
  3627. datetime(2010, 1, 1, 0, 0, 2))
  3628. assertEq(-1 * Second(), datetime(2010, 1, 1, 0, 0, 1),
  3629. datetime(2010, 1, 1))
  3630. self.assertEqual(Second(3) + Second(2), Second(5))
  3631. self.assertEqual(Second(3) - Second(2), Second())
  3632. def test_Millisecond(self):
  3633. assertEq(Milli(), datetime(2010, 1, 1),
  3634. datetime(2010, 1, 1, 0, 0, 0, 1000))
  3635. assertEq(Milli(-1), datetime(2010, 1, 1, 0,
  3636. 0, 0, 1000), datetime(2010, 1, 1))
  3637. assertEq(Milli(2), datetime(2010, 1, 1),
  3638. datetime(2010, 1, 1, 0, 0, 0, 2000))
  3639. assertEq(2 * Milli(), datetime(2010, 1, 1),
  3640. datetime(2010, 1, 1, 0, 0, 0, 2000))
  3641. assertEq(-1 * Milli(), datetime(2010, 1, 1, 0, 0, 0, 1000),
  3642. datetime(2010, 1, 1))
  3643. self.assertEqual(Milli(3) + Milli(2), Milli(5))
  3644. self.assertEqual(Milli(3) - Milli(2), Milli())
  3645. def test_MillisecondTimestampArithmetic(self):
  3646. assertEq(Milli(), Timestamp('2010-01-01'),
  3647. Timestamp('2010-01-01 00:00:00.001'))
  3648. assertEq(Milli(-1), Timestamp('2010-01-01 00:00:00.001'),
  3649. Timestamp('2010-01-01'))
  3650. def test_Microsecond(self):
  3651. assertEq(Micro(), datetime(2010, 1, 1),
  3652. datetime(2010, 1, 1, 0, 0, 0, 1))
  3653. assertEq(Micro(-1), datetime(2010, 1, 1,
  3654. 0, 0, 0, 1), datetime(2010, 1, 1))
  3655. assertEq(2 * Micro(), datetime(2010, 1, 1),
  3656. datetime(2010, 1, 1, 0, 0, 0, 2))
  3657. assertEq(-1 * Micro(), datetime(2010, 1, 1, 0, 0, 0, 1),
  3658. datetime(2010, 1, 1))
  3659. self.assertEqual(Micro(3) + Micro(2), Micro(5))
  3660. self.assertEqual(Micro(3) - Micro(2), Micro())
  3661. def test_NanosecondGeneric(self):
  3662. timestamp = Timestamp(datetime(2010, 1, 1))
  3663. self.assertEqual(timestamp.nanosecond, 0)
  3664. result = timestamp + Nano(10)
  3665. self.assertEqual(result.nanosecond, 10)
  3666. reverse_result = Nano(10) + timestamp
  3667. self.assertEqual(reverse_result.nanosecond, 10)
  3668. def test_Nanosecond(self):
  3669. timestamp = Timestamp(datetime(2010, 1, 1))
  3670. assertEq(Nano(), timestamp, timestamp + np.timedelta64(1, 'ns'))
  3671. assertEq(Nano(-1), timestamp + np.timedelta64(1, 'ns'), timestamp)
  3672. assertEq(2 * Nano(), timestamp, timestamp + np.timedelta64(2, 'ns'))
  3673. assertEq(-1 * Nano(), timestamp + np.timedelta64(1, 'ns'), timestamp)
  3674. self.assertEqual(Nano(3) + Nano(2), Nano(5))
  3675. self.assertEqual(Nano(3) - Nano(2), Nano())
  3676. # GH9284
  3677. self.assertEqual(Nano(1) + Nano(10), Nano(11))
  3678. self.assertEqual(Nano(5) + Micro(1), Nano(1005))
  3679. self.assertEqual(Micro(5) + Nano(1), Nano(5001))
  3680. def test_tick_zero(self):
  3681. for t1 in self.ticks:
  3682. for t2 in self.ticks:
  3683. self.assertEqual(t1(0), t2(0))
  3684. self.assertEqual(t1(0) + t2(0), t1(0))
  3685. if t1 is not Nano:
  3686. self.assertEqual(t1(2) + t2(0), t1(2))
  3687. if t1 is Nano:
  3688. self.assertEqual(t1(2) + Nano(0), t1(2))
  3689. def test_tick_equalities(self):
  3690. for t in self.ticks:
  3691. self.assertEqual(t(3), t(3))
  3692. self.assertEqual(t(), t(1))
  3693. # not equals
  3694. self.assertNotEqual(t(3), t(2))
  3695. self.assertNotEqual(t(3), t(-3))
  3696. def test_tick_operators(self):
  3697. for t in self.ticks:
  3698. self.assertEqual(t(3) + t(2), t(5))
  3699. self.assertEqual(t(3) - t(2), t(1))
  3700. self.assertEqual(t(800) + t(300), t(1100))
  3701. self.assertEqual(t(1000) - t(5), t(995))
  3702. def test_tick_offset(self):
  3703. for t in self.ticks:
  3704. self.assertFalse(t().isAnchored())
  3705. def test_compare_ticks(self):
  3706. for kls in self.ticks:
  3707. three = kls(3)
  3708. four = kls(4)
  3709. for _ in range(10):
  3710. self.assertTrue(three < kls(4))
  3711. self.assertTrue(kls(3) < four)
  3712. self.assertTrue(four > kls(3))
  3713. self.assertTrue(kls(4) > three)
  3714. self.assertTrue(kls(3) == kls(3))
  3715. self.assertTrue(kls(3) != kls(4))
  3716. class TestOffsetNames(tm.TestCase):
  3717. def test_get_offset_name(self):
  3718. self.assertEqual(BDay().freqstr, 'B')
  3719. self.assertEqual(BDay(2).freqstr, '2B')
  3720. self.assertEqual(BMonthEnd().freqstr, 'BM')
  3721. self.assertEqual(Week(weekday=0).freqstr, 'W-MON')
  3722. self.assertEqual(Week(weekday=1).freqstr, 'W-TUE')
  3723. self.assertEqual(Week(weekday=2).freqstr, 'W-WED')
  3724. self.assertEqual(Week(weekday=3).freqstr, 'W-THU')
  3725. self.assertEqual(Week(weekday=4).freqstr, 'W-FRI')
  3726. self.assertEqual(LastWeekOfMonth(
  3727. weekday=WeekDay.SUN).freqstr, "LWOM-SUN")
  3728. self.assertEqual(
  3729. makeFY5253LastOfMonthQuarter(weekday=1, startingMonth=3,
  3730. qtr_with_extra_week=4).freqstr,
  3731. "REQ-L-MAR-TUE-4")
  3732. self.assertEqual(
  3733. makeFY5253NearestEndMonthQuarter(weekday=1, startingMonth=3,
  3734. qtr_with_extra_week=3).freqstr,
  3735. "REQ-N-MAR-TUE-3")
  3736. def test_get_offset():
  3737. with tm.assertRaisesRegexp(ValueError, _INVALID_FREQ_ERROR):
  3738. get_offset('gibberish')
  3739. with tm.assertRaisesRegexp(ValueError, _INVALID_FREQ_ERROR):
  3740. get_offset('QS-JAN-B')
  3741. pairs = [
  3742. ('B', BDay()), ('b', BDay()), ('bm', BMonthEnd()),
  3743. ('Bm', BMonthEnd()), ('W-MON', Week(weekday=0)),
  3744. ('W-TUE', Week(weekday=1)), ('W-WED', Week(weekday=2)),
  3745. ('W-THU', Week(weekday=3)), ('W-FRI', Week(weekday=4)),
  3746. ("RE-N-DEC-MON", makeFY5253NearestEndMonth(weekday=0,
  3747. startingMonth=12)),
  3748. ("RE-L-DEC-TUE", makeFY5253LastOfMonth(weekday=1, startingMonth=12)),
  3749. ("REQ-L-MAR-TUE-4", makeFY5253LastOfMonthQuarter(
  3750. weekday=1, startingMonth=3, qtr_with_extra_week=4)),
  3751. ("REQ-L-DEC-MON-3", makeFY5253LastOfMonthQuarter(
  3752. weekday=0, startingMonth=12, qtr_with_extra_week=3)),
  3753. ("REQ-N-DEC-MON-3", makeFY5253NearestEndMonthQuarter(
  3754. weekday=0, startingMonth=12, qtr_with_extra_week=3)),
  3755. ]
  3756. for name, expected in pairs:
  3757. offset = get_offset(name)
  3758. assert offset == expected, ("Expected %r to yield %r (actual: %r)" %
  3759. (name, expected, offset))
  3760. def test_get_offset_legacy():
  3761. pairs = [('w@Sat', Week(weekday=5))]
  3762. for name, expected in pairs:
  3763. with tm.assertRaisesRegexp(ValueError, _INVALID_FREQ_ERROR):
  3764. get_offset(name)
  3765. class TestParseTimeString(tm.TestCase):
  3766. def test_parse_time_string(self):
  3767. (date, parsed, reso) = parse_time_string('4Q1984')
  3768. (date_lower, parsed_lower, reso_lower) = parse_time_string('4q1984')
  3769. self.assertEqual(date, date_lower)
  3770. self.assertEqual(parsed, parsed_lower)
  3771. self.assertEqual(reso, reso_lower)
  3772. def test_parse_time_quarter_w_dash(self):
  3773. # https://github.com/pydata/pandas/issue/9688
  3774. pairs = [('1988-Q2', '1988Q2'), ('2Q-1988', '2Q1988'), ]
  3775. for dashed, normal in pairs:
  3776. (date_dash, parsed_dash, reso_dash) = parse_time_string(dashed)
  3777. (date, parsed, reso) = parse_time_string(normal)
  3778. self.assertEqual(date_dash, date)
  3779. self.assertEqual(parsed_dash, parsed)
  3780. self.assertEqual(reso_dash, reso)
  3781. self.assertRaises(DateParseError, parse_time_string, "-2Q1992")
  3782. self.assertRaises(DateParseError, parse_time_string, "2-Q1992")
  3783. self.assertRaises(DateParseError, parse_time_string, "4-4Q1992")
  3784. def test_get_standard_freq():
  3785. with tm.assert_produces_warning(FutureWarning, check_stacklevel=False):
  3786. fstr = get_standard_freq('W')
  3787. with tm.assert_produces_warning(FutureWarning, check_stacklevel=False):
  3788. assert fstr == get_standard_freq('w')
  3789. with tm.assert_produces_warning(FutureWarning, check_stacklevel=False):
  3790. assert fstr == get_standard_freq('1w')
  3791. with tm.assert_produces_warning(FutureWarning, check_stacklevel=False):
  3792. assert fstr == get_standard_freq(('W', 1))
  3793. with tm.assertRaisesRegexp(ValueError, _INVALID_FREQ_ERROR):
  3794. with tm.assert_produces_warning(FutureWarning, check_stacklevel=False):
  3795. get_standard_freq('WeEk')
  3796. with tm.assert_produces_warning(FutureWarning, check_stacklevel=False):
  3797. fstr = get_standard_freq('5Q')
  3798. with tm.assert_produces_warning(FutureWarning, check_stacklevel=False):
  3799. assert fstr == get_standard_freq('5q')
  3800. with tm.assertRaisesRegexp(ValueError, _INVALID_FREQ_ERROR):
  3801. with tm.assert_produces_warning(FutureWarning, check_stacklevel=False):
  3802. get_standard_freq('5QuarTer')
  3803. with tm.assert_produces_warning(FutureWarning, check_stacklevel=False):
  3804. assert fstr == get_standard_freq(('q', 5))
  3805. def test_quarterly_dont_normalize():
  3806. date = datetime(2012, 3, 31, 5, 30)
  3807. offsets = (QuarterBegin, QuarterEnd, BQuarterEnd, BQuarterBegin)
  3808. for klass in offsets:
  3809. result = date + klass()
  3810. assert (result.time() == date.time())
  3811. class TestOffsetAliases(tm.TestCase):
  3812. def setUp(self):
  3813. _offset_map.clear()
  3814. def test_alias_equality(self):
  3815. for k, v in compat.iteritems(_offset_map):
  3816. if v is None:
  3817. continue
  3818. self.assertEqual(k, v.copy())
  3819. def test_rule_code(self):
  3820. lst = ['M', 'MS', 'BM', 'BMS', 'D', 'B', 'H', 'T', 'S', 'L', 'U']
  3821. for k in lst:
  3822. self.assertEqual(k, get_offset(k).rule_code)
  3823. # should be cached - this is kind of an internals test...
  3824. assert k in _offset_map
  3825. self.assertEqual(k, (get_offset(k) * 3).rule_code)
  3826. suffix_lst = ['MON', 'TUE', 'WED', 'THU', 'FRI', 'SAT', 'SUN']
  3827. base = 'W'
  3828. for v in suffix_lst:
  3829. alias = '-'.join([base, v])
  3830. self.assertEqual(alias, get_offset(alias).rule_code)
  3831. self.assertEqual(alias, (get_offset(alias) * 5).rule_code)
  3832. suffix_lst = ['JAN', 'FEB', 'MAR', 'APR', 'MAY', 'JUN', 'JUL', 'AUG',
  3833. 'SEP', 'OCT', 'NOV', 'DEC']
  3834. base_lst = ['A', 'AS', 'BA', 'BAS', 'Q', 'QS', 'BQ', 'BQS']
  3835. for base in base_lst:
  3836. for v in suffix_lst:
  3837. alias = '-'.join([base, v])
  3838. self.assertEqual(alias, get_offset(alias).rule_code)
  3839. self.assertEqual(alias, (get_offset(alias) * 5).rule_code)
  3840. lst = ['M', 'D', 'B', 'H', 'T', 'S', 'L', 'U']
  3841. for k in lst:
  3842. code, stride = get_freq_code('3' + k)
  3843. self.assertTrue(isinstance(code, int))
  3844. self.assertEqual(stride, 3)
  3845. self.assertEqual(k, _get_freq_str(code))
  3846. def test_apply_ticks():
  3847. result = offsets.Hour(3).apply(offsets.Hour(4))
  3848. exp = offsets.Hour(7)
  3849. assert (result == exp)
  3850. def test_delta_to_tick():
  3851. delta = timedelta(3)
  3852. tick = offsets._delta_to_tick(delta)
  3853. assert (tick == offsets.Day(3))
  3854. def test_dateoffset_misc():
  3855. oset = offsets.DateOffset(months=2, days=4)
  3856. # it works
  3857. oset.freqstr
  3858. assert (not offsets.DateOffset(months=2) == 2)
  3859. def test_freq_offsets():
  3860. off = BDay(1, offset=timedelta(0, 1800))
  3861. assert (off.freqstr == 'B+30Min')
  3862. off = BDay(1, offset=timedelta(0, -1800))
  3863. assert (off.freqstr == 'B-30Min')
  3864. def get_all_subclasses(cls):
  3865. ret = set()
  3866. this_subclasses = cls.__subclasses__()
  3867. ret = ret | set(this_subclasses)
  3868. for this_subclass in this_subclasses:
  3869. ret | get_all_subclasses(this_subclass)
  3870. return ret
  3871. class TestCaching(tm.TestCase):
  3872. # as of GH 6479 (in 0.14.0), offset caching is turned off
  3873. # as of v0.12.0 only BusinessMonth/Quarter were actually caching
  3874. def setUp(self):
  3875. _daterange_cache.clear()
  3876. _offset_map.clear()
  3877. def run_X_index_creation(self, cls):
  3878. inst1 = cls()
  3879. if not inst1.isAnchored():
  3880. self.assertFalse(inst1._should_cache(), cls)
  3881. return
  3882. self.assertTrue(inst1._should_cache(), cls)
  3883. DatetimeIndex(start=datetime(2013, 1, 31), end=datetime(2013, 3, 31),
  3884. freq=inst1, normalize=True)
  3885. self.assertTrue(cls() in _daterange_cache, cls)
  3886. def test_should_cache_month_end(self):
  3887. self.assertFalse(MonthEnd()._should_cache())
  3888. def test_should_cache_bmonth_end(self):
  3889. self.assertFalse(BusinessMonthEnd()._should_cache())
  3890. def test_should_cache_week_month(self):
  3891. self.assertFalse(WeekOfMonth(weekday=1, week=2)._should_cache())
  3892. def test_all_cacheableoffsets(self):
  3893. for subclass in get_all_subclasses(CacheableOffset):
  3894. if subclass.__name__[0] == "_" \
  3895. or subclass in TestCaching.no_simple_ctr:
  3896. continue
  3897. self.run_X_index_creation(subclass)
  3898. def test_month_end_index_creation(self):
  3899. DatetimeIndex(start=datetime(2013, 1, 31), end=datetime(2013, 3, 31),
  3900. freq=MonthEnd(), normalize=True)
  3901. self.assertFalse(MonthEnd() in _daterange_cache)
  3902. def test_bmonth_end_index_creation(self):
  3903. DatetimeIndex(start=datetime(2013, 1, 31), end=datetime(2013, 3, 29),
  3904. freq=BusinessMonthEnd(), normalize=True)
  3905. self.assertFalse(BusinessMonthEnd() in _daterange_cache)
  3906. def test_week_of_month_index_creation(self):
  3907. inst1 = WeekOfMonth(weekday=1, week=2)
  3908. DatetimeIndex(start=datetime(2013, 1, 31), end=datetime(2013, 3, 29),
  3909. freq=inst1, normalize=True)
  3910. inst2 = WeekOfMonth(weekday=1, week=2)
  3911. self.assertFalse(inst2 in _daterange_cache)
  3912. class TestReprNames(tm.TestCase):
  3913. def test_str_for_named_is_name(self):
  3914. # look at all the amazing combinations!
  3915. month_prefixes = ['A', 'AS', 'BA', 'BAS', 'Q', 'BQ', 'BQS', 'QS']
  3916. names = [prefix + '-' + month
  3917. for prefix in month_prefixes
  3918. for month in ['JAN', 'FEB', 'MAR', 'APR', 'MAY', 'JUN', 'JUL',
  3919. 'AUG', 'SEP', 'OCT', 'NOV', 'DEC']]
  3920. days = ['MON', 'TUE', 'WED', 'THU', 'FRI', 'SAT', 'SUN']
  3921. names += ['W-' + day for day in days]
  3922. names += ['WOM-' + week + day
  3923. for week in ('1', '2', '3', '4') for day in days]
  3924. _offset_map.clear()
  3925. for name in names:
  3926. offset = get_offset(name)
  3927. self.assertEqual(offset.freqstr, name)
  3928. def get_utc_offset_hours(ts):
  3929. # take a Timestamp and compute total hours of utc offset
  3930. o = ts.utcoffset()
  3931. return (o.days * 24 * 3600 + o.seconds) / 3600.0
  3932. class TestDST(tm.TestCase):
  3933. """
  3934. test DateOffset additions over Daylight Savings Time
  3935. """
  3936. # one microsecond before the DST transition
  3937. ts_pre_fallback = "2013-11-03 01:59:59.999999"
  3938. ts_pre_springfwd = "2013-03-10 01:59:59.999999"
  3939. # test both basic names and dateutil timezones
  3940. timezone_utc_offsets = {
  3941. 'US/Eastern': dict(utc_offset_daylight=-4,
  3942. utc_offset_standard=-5, ),
  3943. 'dateutil/US/Pacific': dict(utc_offset_daylight=-7,
  3944. utc_offset_standard=-8, )
  3945. }
  3946. valid_date_offsets_singular = [
  3947. 'weekday', 'day', 'hour', 'minute', 'second', 'microsecond'
  3948. ]
  3949. valid_date_offsets_plural = [
  3950. 'weeks', 'days',
  3951. 'hours', 'minutes', 'seconds',
  3952. 'milliseconds', 'microseconds'
  3953. ]
  3954. def _test_all_offsets(self, n, **kwds):
  3955. valid_offsets = self.valid_date_offsets_plural if n > 1 \
  3956. else self.valid_date_offsets_singular
  3957. for name in valid_offsets:
  3958. self._test_offset(offset_name=name, offset_n=n, **kwds)
  3959. def _test_offset(self, offset_name, offset_n, tstart, expected_utc_offset):
  3960. offset = DateOffset(**{offset_name: offset_n})
  3961. t = tstart + offset
  3962. if expected_utc_offset is not None:
  3963. self.assertTrue(get_utc_offset_hours(t) == expected_utc_offset)
  3964. if offset_name == 'weeks':
  3965. # dates should match
  3966. self.assertTrue(t.date() == timedelta(days=7 * offset.kwds[
  3967. 'weeks']) + tstart.date())
  3968. # expect the same day of week, hour of day, minute, second, ...
  3969. self.assertTrue(t.dayofweek == tstart.dayofweek and t.hour ==
  3970. tstart.hour and t.minute == tstart.minute and
  3971. t.second == tstart.second)
  3972. elif offset_name == 'days':
  3973. # dates should match
  3974. self.assertTrue(timedelta(offset.kwds['days']) + tstart.date() ==
  3975. t.date())
  3976. # expect the same hour of day, minute, second, ...
  3977. self.assertTrue(t.hour == tstart.hour and
  3978. t.minute == tstart.minute and
  3979. t.second == tstart.second)
  3980. elif offset_name in self.valid_date_offsets_singular:
  3981. # expect the signular offset value to match between tstart and t
  3982. datepart_offset = getattr(t, offset_name
  3983. if offset_name != 'weekday' else
  3984. 'dayofweek')
  3985. self.assertTrue(datepart_offset == offset.kwds[offset_name])
  3986. else:
  3987. # the offset should be the same as if it was done in UTC
  3988. self.assertTrue(t == (tstart.tz_convert('UTC') + offset
  3989. ).tz_convert('US/Pacific'))
  3990. def _make_timestamp(self, string, hrs_offset, tz):
  3991. if hrs_offset >= 0:
  3992. offset_string = '{hrs:02d}00'.format(hrs=hrs_offset)
  3993. else:
  3994. offset_string = '-{hrs:02d}00'.format(hrs=-1 * hrs_offset)
  3995. return Timestamp(string + offset_string).tz_convert(tz)
  3996. def test_fallback_plural(self):
  3997. """test moving from daylight savings to standard time"""
  3998. for tz, utc_offsets in self.timezone_utc_offsets.items():
  3999. hrs_pre = utc_offsets['utc_offset_daylight']
  4000. hrs_post = utc_offsets['utc_offset_standard']
  4001. self._test_all_offsets(
  4002. n=3, tstart=self._make_timestamp(self.ts_pre_fallback,
  4003. hrs_pre, tz),
  4004. expected_utc_offset=hrs_post)
  4005. def test_springforward_plural(self):
  4006. """test moving from standard to daylight savings"""
  4007. for tz, utc_offsets in self.timezone_utc_offsets.items():
  4008. hrs_pre = utc_offsets['utc_offset_standard']
  4009. hrs_post = utc_offsets['utc_offset_daylight']
  4010. self._test_all_offsets(
  4011. n=3, tstart=self._make_timestamp(self.ts_pre_springfwd,
  4012. hrs_pre, tz),
  4013. expected_utc_offset=hrs_post)
  4014. def test_fallback_singular(self):
  4015. # in the case of signular offsets, we dont neccesarily know which utc
  4016. # offset the new Timestamp will wind up in (the tz for 1 month may be
  4017. # different from 1 second) so we don't specify an expected_utc_offset
  4018. for tz, utc_offsets in self.timezone_utc_offsets.items():
  4019. hrs_pre = utc_offsets['utc_offset_standard']
  4020. self._test_all_offsets(n=1, tstart=self._make_timestamp(
  4021. self.ts_pre_fallback, hrs_pre, tz), expected_utc_offset=None)
  4022. def test_springforward_singular(self):
  4023. for tz, utc_offsets in self.timezone_utc_offsets.items():
  4024. hrs_pre = utc_offsets['utc_offset_standard']
  4025. self._test_all_offsets(n=1, tstart=self._make_timestamp(
  4026. self.ts_pre_springfwd, hrs_pre, tz), expected_utc_offset=None)
  4027. def test_all_offset_classes(self):
  4028. tests = {MonthBegin: ['11/2/2012', '12/1/2012'],
  4029. MonthEnd: ['11/2/2012', '11/30/2012'],
  4030. BMonthBegin: ['11/2/2012', '12/3/2012'],
  4031. BMonthEnd: ['11/2/2012', '11/30/2012'],
  4032. CBMonthBegin: ['11/2/2012', '12/3/2012'],
  4033. CBMonthEnd: ['11/2/2012', '11/30/2012'],
  4034. SemiMonthBegin: ['11/2/2012', '11/15/2012'],
  4035. SemiMonthEnd: ['11/2/2012', '11/15/2012'],
  4036. Week: ['11/2/2012', '11/9/2012'],
  4037. YearBegin: ['11/2/2012', '1/1/2013'],
  4038. YearEnd: ['11/2/2012', '12/31/2012'],
  4039. BYearBegin: ['11/2/2012', '1/1/2013'],
  4040. BYearEnd: ['11/2/2012', '12/31/2012'],
  4041. QuarterBegin: ['11/2/2012', '12/1/2012'],
  4042. QuarterEnd: ['11/2/2012', '12/31/2012'],
  4043. BQuarterBegin: ['11/2/2012', '12/3/2012'],
  4044. BQuarterEnd: ['11/2/2012', '12/31/2012'],
  4045. Day: ['11/4/2012', '11/4/2012 23:00']}
  4046. for offset, test_values in iteritems(tests):
  4047. first = Timestamp(test_values[0], tz='US/Eastern') + offset()
  4048. second = Timestamp(test_values[1], tz='US/Eastern')
  4049. self.assertEqual(first, second, msg=str(offset))
  4050. if __name__ == '__main__':
  4051. nose.runmodule(argv=[__file__, '-vvs', '-x', '--pdb', '--pdb-failure'],
  4052. exit=False)