Development of an internal social media platform with personalised dashboards for students
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

test_croniter.py 30KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837
  1. #!/usr/bin/env python
  2. # -*- coding: utf-8 -*-
  3. import unittest
  4. from datetime import datetime
  5. from time import sleep
  6. import pytz
  7. from croniter import croniter, CroniterBadDateError, CroniterBadCronError, CroniterNotAlphaError
  8. from croniter.tests import base
  9. class CroniterTest(base.TestCase):
  10. def testSecond(self):
  11. base = datetime(2012, 4, 6, 13, 26, 10)
  12. itr = croniter('*/1 * * * * *', base)
  13. n1 = itr.get_next(datetime)
  14. self.assertEqual(base.year, n1.year)
  15. self.assertEqual(base.month, n1.month)
  16. self.assertEqual(base.day, n1.day)
  17. self.assertEqual(base.hour, n1.hour)
  18. self.assertEqual(base.minute, n1.minute)
  19. self.assertEqual(base.second + 1, n1.second)
  20. def testSecondRepeat(self):
  21. base = datetime(2012, 4, 6, 13, 26, 36)
  22. itr = croniter('* * * * * */15', base)
  23. n1 = itr.get_next(datetime)
  24. n2 = itr.get_next(datetime)
  25. n3 = itr.get_next(datetime)
  26. self.assertEqual(base.year, n1.year)
  27. self.assertEqual(base.month, n1.month)
  28. self.assertEqual(base.day, n1.day)
  29. self.assertEqual(base.hour, n1.hour)
  30. self.assertEqual(base.minute, n1.minute)
  31. self.assertEqual(45, n1.second)
  32. self.assertEqual(base.year, n2.year)
  33. self.assertEqual(base.month, n2.month)
  34. self.assertEqual(base.day, n2.day)
  35. self.assertEqual(base.hour, n2.hour)
  36. self.assertEqual(base.minute + 1, n2.minute)
  37. self.assertEqual(0, n2.second)
  38. self.assertEqual(base.year, n3.year)
  39. self.assertEqual(base.month, n3.month)
  40. self.assertEqual(base.day, n3.day)
  41. self.assertEqual(base.hour, n3.hour)
  42. self.assertEqual(base.minute + 1, n3.minute)
  43. self.assertEqual(15, n3.second)
  44. def testMinute(self):
  45. # minute asterisk
  46. base = datetime(2010, 1, 23, 12, 18)
  47. itr = croniter('*/1 * * * *', base)
  48. n1 = itr.get_next(datetime) # 19
  49. self.assertEqual(base.year, n1.year)
  50. self.assertEqual(base.month, n1.month)
  51. self.assertEqual(base.day, n1.day)
  52. self.assertEqual(base.hour, n1.hour)
  53. self.assertEqual(base.minute, n1.minute - 1)
  54. for i in range(39): # ~ 58
  55. itr.get_next()
  56. n2 = itr.get_next(datetime)
  57. self.assertEqual(n2.minute, 59)
  58. n3 = itr.get_next(datetime)
  59. self.assertEqual(n3.minute, 0)
  60. self.assertEqual(n3.hour, 13)
  61. itr = croniter('*/5 * * * *', base)
  62. n4 = itr.get_next(datetime)
  63. self.assertEqual(n4.minute, 20)
  64. for i in range(6):
  65. itr.get_next()
  66. n5 = itr.get_next(datetime)
  67. self.assertEqual(n5.minute, 55)
  68. n6 = itr.get_next(datetime)
  69. self.assertEqual(n6.minute, 0)
  70. self.assertEqual(n6.hour, 13)
  71. def testHour(self):
  72. base = datetime(2010, 1, 24, 12, 2)
  73. itr = croniter('0 */3 * * *', base)
  74. n1 = itr.get_next(datetime)
  75. self.assertEqual(n1.hour, 15)
  76. self.assertEqual(n1.minute, 0)
  77. for i in range(2):
  78. itr.get_next()
  79. n2 = itr.get_next(datetime)
  80. self.assertEqual(n2.hour, 0)
  81. self.assertEqual(n2.day, 25)
  82. def testDay(self):
  83. base = datetime(2010, 2, 24, 12, 9)
  84. itr = croniter('0 0 */3 * *', base)
  85. n1 = itr.get_next(datetime)
  86. # 1 4 7 10 13 16 19 22 25 28
  87. self.assertEqual(n1.day, 25)
  88. n2 = itr.get_next(datetime)
  89. self.assertEqual(n2.day, 28)
  90. n3 = itr.get_next(datetime)
  91. self.assertEqual(n3.day, 1)
  92. self.assertEqual(n3.month, 3)
  93. # test leap year
  94. base = datetime(1996, 2, 27)
  95. itr = croniter('0 0 * * *', base)
  96. n1 = itr.get_next(datetime)
  97. self.assertEqual(n1.day, 28)
  98. self.assertEqual(n1.month, 2)
  99. n2 = itr.get_next(datetime)
  100. self.assertEqual(n2.day, 29)
  101. self.assertEqual(n2.month, 2)
  102. base2 = datetime(2000, 2, 27)
  103. itr2 = croniter('0 0 * * *', base2)
  104. n3 = itr2.get_next(datetime)
  105. self.assertEqual(n3.day, 28)
  106. self.assertEqual(n3.month, 2)
  107. n4 = itr2.get_next(datetime)
  108. self.assertEqual(n4.day, 29)
  109. self.assertEqual(n4.month, 2)
  110. def testWeekDay(self):
  111. base = datetime(2010, 2, 25)
  112. itr = croniter('0 0 * * sat', base)
  113. n1 = itr.get_next(datetime)
  114. self.assertEqual(n1.isoweekday(), 6)
  115. self.assertEqual(n1.day, 27)
  116. n2 = itr.get_next(datetime)
  117. self.assertEqual(n2.isoweekday(), 6)
  118. self.assertEqual(n2.day, 6)
  119. self.assertEqual(n2.month, 3)
  120. base = datetime(2010, 1, 25)
  121. itr = croniter('0 0 1 * wed', base)
  122. n1 = itr.get_next(datetime)
  123. self.assertEqual(n1.month, 1)
  124. self.assertEqual(n1.day, 27)
  125. self.assertEqual(n1.year, 2010)
  126. n2 = itr.get_next(datetime)
  127. self.assertEqual(n2.month, 2)
  128. self.assertEqual(n2.day, 1)
  129. self.assertEqual(n2.year, 2010)
  130. n3 = itr.get_next(datetime)
  131. self.assertEqual(n3.month, 2)
  132. self.assertEqual(n3.day, 3)
  133. self.assertEqual(n3.year, 2010)
  134. def testNthWeekDay(self):
  135. base = datetime(2010, 2, 25)
  136. itr = croniter('0 0 * * sat#1', base)
  137. n1 = itr.get_next(datetime)
  138. self.assertEqual(n1.isoweekday(), 6)
  139. self.assertEqual(n1.day, 6)
  140. self.assertEqual(n1.month, 3)
  141. n2 = itr.get_next(datetime)
  142. self.assertEqual(n2.isoweekday(), 6)
  143. self.assertEqual(n2.day, 3)
  144. self.assertEqual(n2.month, 4)
  145. base = datetime(2010, 1, 25)
  146. itr = croniter('0 0 * * wed#5', base)
  147. n1 = itr.get_next(datetime)
  148. self.assertEqual(n1.month, 3)
  149. self.assertEqual(n1.day, 31)
  150. self.assertEqual(n1.year, 2010)
  151. n2 = itr.get_next(datetime)
  152. self.assertEqual(n2.month, 6)
  153. self.assertEqual(n2.day, 30)
  154. self.assertEqual(n2.year, 2010)
  155. n3 = itr.get_next(datetime)
  156. self.assertEqual(n3.month, 9)
  157. self.assertEqual(n3.day, 29)
  158. self.assertEqual(n3.year, 2010)
  159. def testWeekDayDayAnd(self):
  160. base = datetime(2010, 1, 25)
  161. itr = croniter('0 0 1 * mon', base, day_or=False)
  162. n1 = itr.get_next(datetime)
  163. self.assertEqual(n1.month, 2)
  164. self.assertEqual(n1.day, 1)
  165. self.assertEqual(n1.year, 2010)
  166. n2 = itr.get_next(datetime)
  167. self.assertEqual(n2.month, 3)
  168. self.assertEqual(n2.day, 1)
  169. self.assertEqual(n2.year, 2010)
  170. n3 = itr.get_next(datetime)
  171. self.assertEqual(n3.month, 11)
  172. self.assertEqual(n3.day, 1)
  173. self.assertEqual(n3.year, 2010)
  174. def testMonth(self):
  175. base = datetime(2010, 1, 25)
  176. itr = croniter('0 0 1 * *', base)
  177. n1 = itr.get_next(datetime)
  178. self.assertEqual(n1.month, 2)
  179. self.assertEqual(n1.day, 1)
  180. n2 = itr.get_next(datetime)
  181. self.assertEqual(n2.month, 3)
  182. self.assertEqual(n2.day, 1)
  183. for i in range(8):
  184. itr.get_next()
  185. n3 = itr.get_next(datetime)
  186. self.assertEqual(n3.month, 12)
  187. self.assertEqual(n3.year, 2010)
  188. n4 = itr.get_next(datetime)
  189. self.assertEqual(n4.month, 1)
  190. self.assertEqual(n4.year, 2011)
  191. def testLastDayOfMonth(self):
  192. base = datetime(2015, 9, 4)
  193. itr = croniter('0 0 l * *', base)
  194. n1 = itr.get_next(datetime)
  195. self.assertEqual(n1.month, 9)
  196. self.assertEqual(n1.day, 30)
  197. n2 = itr.get_next(datetime)
  198. self.assertEqual(n2.month, 10)
  199. self.assertEqual(n2.day, 31)
  200. n3 = itr.get_next(datetime)
  201. self.assertEqual(n3.month, 11)
  202. self.assertEqual(n3.day, 30)
  203. n4 = itr.get_next(datetime)
  204. self.assertEqual(n4.month, 12)
  205. self.assertEqual(n4.day, 31)
  206. def testPrevLastDayOfMonth(self):
  207. base = datetime(2009, 12, 31, hour=20)
  208. itr = croniter('0 0 l * *', base)
  209. n1 = itr.get_prev(datetime)
  210. self.assertEqual(n1.month, 12)
  211. self.assertEqual(n1.day, 31)
  212. base = datetime(2009, 12, 31)
  213. itr = croniter('0 0 l * *', base)
  214. n1 = itr.get_prev(datetime)
  215. self.assertEqual(n1.month, 11)
  216. self.assertEqual(n1.day, 30)
  217. base = datetime(2010, 1, 5)
  218. itr = croniter('0 0 l * *', base)
  219. n1 = itr.get_prev(datetime)
  220. self.assertEqual(n1.month, 12)
  221. self.assertEqual(n1.day, 31)
  222. n1 = itr.get_prev(datetime)
  223. self.assertEqual(n1.month, 11)
  224. self.assertEqual(n1.day, 30)
  225. n1 = itr.get_prev(datetime)
  226. self.assertEqual(n1.month, 10)
  227. self.assertEqual(n1.day, 31)
  228. n1 = itr.get_prev(datetime)
  229. self.assertEqual(n1.month, 9)
  230. self.assertEqual(n1.day, 30)
  231. base = datetime(2010, 1, 31, minute=2)
  232. itr = croniter('* * l * *', base)
  233. n1 = itr.get_prev(datetime)
  234. self.assertEqual(n1.month, 1)
  235. self.assertEqual(n1.day, 31)
  236. n1 = itr.get_prev(datetime)
  237. self.assertEqual(n1.month, 1)
  238. self.assertEqual(n1.day, 31)
  239. n1 = itr.get_prev(datetime)
  240. self.assertEqual(n1.month, 12)
  241. self.assertEqual(n1.day, 31)
  242. n1 = itr.get_prev(datetime)
  243. self.assertEqual(n1.month, 12)
  244. self.assertEqual(n1.day, 31)
  245. def testError(self):
  246. itr = croniter('* * * * *')
  247. self.assertRaises(TypeError, itr.get_next, str)
  248. self.assertRaises(ValueError, croniter, '* * * *')
  249. self.assertRaises(ValueError, croniter, '* * 5-1 * *')
  250. self.assertRaises(ValueError, croniter, '-90 * * * *')
  251. self.assertRaises(ValueError, croniter, 'a * * * *')
  252. self.assertRaises(ValueError, croniter, '* * * janu-jun *')
  253. def testSundayToThursdayWithAlphaConversion(self):
  254. base = datetime(2010, 8, 25, 15, 56) # wednesday
  255. itr = croniter("30 22 * * sun-thu", base)
  256. next = itr.get_next(datetime)
  257. self.assertEqual(base.year, next.year)
  258. self.assertEqual(base.month, next.month)
  259. self.assertEqual(base.day, next.day)
  260. self.assertEqual(22, next.hour)
  261. self.assertEqual(30, next.minute)
  262. def testPrevMinute(self):
  263. base = datetime(2010, 8, 25, 15, 56)
  264. itr = croniter('*/1 * * * *', base)
  265. prev = itr.get_prev(datetime)
  266. self.assertEqual(base.year, prev.year)
  267. self.assertEqual(base.month, prev.month)
  268. self.assertEqual(base.day, prev.day)
  269. self.assertEqual(base.hour, prev.hour)
  270. self.assertEqual(base.minute, prev.minute + 1)
  271. base = datetime(2010, 8, 25, 15, 0)
  272. itr = croniter('*/1 * * * *', base)
  273. prev = itr.get_prev(datetime)
  274. self.assertEqual(base.year, prev.year)
  275. self.assertEqual(base.month, prev.month)
  276. self.assertEqual(base.day, prev.day)
  277. self.assertEqual(base.hour, prev.hour + 1)
  278. self.assertEqual(59, prev.minute)
  279. base = datetime(2010, 8, 25, 0, 0)
  280. itr = croniter('*/1 * * * *', base)
  281. prev = itr.get_prev(datetime)
  282. self.assertEqual(base.year, prev.year)
  283. self.assertEqual(base.month, prev.month)
  284. self.assertEqual(base.day, prev.day + 1)
  285. self.assertEqual(23, prev.hour)
  286. self.assertEqual(59, prev.minute)
  287. def testPrevDayOfMonthWithCrossing(self):
  288. """
  289. Test getting previous occurrence that crosses into previous month.
  290. """
  291. base = datetime(2012, 3, 15, 0, 0)
  292. itr = croniter('0 0 22 * *', base)
  293. prev = itr.get_prev(datetime)
  294. self.assertEqual(prev.year, 2012)
  295. self.assertEqual(prev.month, 2)
  296. self.assertEqual(prev.day, 22)
  297. self.assertEqual(prev.hour, 0)
  298. self.assertEqual(prev.minute, 0)
  299. def testPrevWeekDay(self):
  300. base = datetime(2010, 8, 25, 15, 56)
  301. itr = croniter('0 0 * * sat,sun', base)
  302. prev1 = itr.get_prev(datetime)
  303. self.assertEqual(prev1.year, base.year)
  304. self.assertEqual(prev1.month, base.month)
  305. self.assertEqual(prev1.day, 22)
  306. self.assertEqual(prev1.hour, 0)
  307. self.assertEqual(prev1.minute, 0)
  308. prev2 = itr.get_prev(datetime)
  309. self.assertEqual(prev2.year, base.year)
  310. self.assertEqual(prev2.month, base.month)
  311. self.assertEqual(prev2.day, 21)
  312. self.assertEqual(prev2.hour, 0)
  313. self.assertEqual(prev2.minute, 0)
  314. prev3 = itr.get_prev(datetime)
  315. self.assertEqual(prev3.year, base.year)
  316. self.assertEqual(prev3.month, base.month)
  317. self.assertEqual(prev3.day, 15)
  318. self.assertEqual(prev3.hour, 0)
  319. self.assertEqual(prev3.minute, 0)
  320. def testPrevNthWeekDay(self):
  321. base = datetime(2010, 8, 25, 15, 56)
  322. itr = croniter('0 0 * * sat#1,sun#2', base)
  323. prev1 = itr.get_prev(datetime)
  324. self.assertEqual(prev1.year, base.year)
  325. self.assertEqual(prev1.month, base.month)
  326. self.assertEqual(prev1.day, 8)
  327. self.assertEqual(prev1.hour, 0)
  328. self.assertEqual(prev1.minute, 0)
  329. prev2 = itr.get_prev(datetime)
  330. self.assertEqual(prev2.year, base.year)
  331. self.assertEqual(prev2.month, base.month)
  332. self.assertEqual(prev2.day, 7)
  333. self.assertEqual(prev2.hour, 0)
  334. self.assertEqual(prev2.minute, 0)
  335. prev3 = itr.get_prev(datetime)
  336. self.assertEqual(prev3.year, base.year)
  337. self.assertEqual(prev3.month, 7)
  338. self.assertEqual(prev3.day, 11)
  339. self.assertEqual(prev3.hour, 0)
  340. self.assertEqual(prev3.minute, 0)
  341. def testPrevWeekDay2(self):
  342. base = datetime(2010, 8, 25, 15, 56)
  343. itr = croniter('10 0 * * 0', base)
  344. prev = itr.get_prev(datetime)
  345. self.assertEqual(prev.day, 22)
  346. self.assertEqual(prev.hour, 0)
  347. self.assertEqual(prev.minute, 10)
  348. def testISOWeekday(self):
  349. base = datetime(2010, 2, 25)
  350. itr = croniter('0 0 * * 7', base)
  351. n1 = itr.get_next(datetime)
  352. self.assertEqual(n1.isoweekday(), 7)
  353. self.assertEqual(n1.day, 28)
  354. n2 = itr.get_next(datetime)
  355. self.assertEqual(n2.isoweekday(), 7)
  356. self.assertEqual(n2.day, 7)
  357. self.assertEqual(n2.month, 3)
  358. def testBug1(self):
  359. base = datetime(2012, 2, 24)
  360. itr = croniter('5 0 */2 * *', base)
  361. n1 = itr.get_prev(datetime)
  362. self.assertEqual(n1.hour, 0)
  363. self.assertEqual(n1.minute, 5)
  364. self.assertEqual(n1.month, 2)
  365. # month starts from 1, 3 .... then 21, 23
  366. # so correct is not 22 but 23
  367. self.assertEqual(n1.day, 23)
  368. def testBug2(self):
  369. base = datetime(2012, 1, 1, 0, 0)
  370. iter = croniter('0 * * 3 *', base)
  371. n1 = iter.get_next(datetime)
  372. self.assertEqual(n1.year, base.year)
  373. self.assertEqual(n1.month, 3)
  374. self.assertEqual(n1.day, base.day)
  375. self.assertEqual(n1.hour, base.hour)
  376. self.assertEqual(n1.minute, base.minute)
  377. n2 = iter.get_next(datetime)
  378. self.assertEqual(n2.year, base.year)
  379. self.assertEqual(n2.month, 3)
  380. self.assertEqual(n2.day, base.day)
  381. self.assertEqual(n2.hour, base.hour + 1)
  382. self.assertEqual(n2.minute, base.minute)
  383. n3 = iter.get_next(datetime)
  384. self.assertEqual(n3.year, base.year)
  385. self.assertEqual(n3.month, 3)
  386. self.assertEqual(n3.day, base.day)
  387. self.assertEqual(n3.hour, base.hour + 2)
  388. self.assertEqual(n3.minute, base.minute)
  389. def testBug3(self):
  390. base = datetime(2013, 3, 1, 12, 17, 34, 257877)
  391. c = croniter('00 03 16,30 * *', base)
  392. n1 = c.get_next(datetime)
  393. self.assertEqual(n1.month, 3)
  394. self.assertEqual(n1.day, 16)
  395. n2 = c.get_next(datetime)
  396. self.assertEqual(n2.month, 3)
  397. self.assertEqual(n2.day, 30)
  398. n3 = c.get_next(datetime)
  399. self.assertEqual(n3.month, 4)
  400. self.assertEqual(n3.day, 16)
  401. n4 = c.get_prev(datetime)
  402. self.assertEqual(n4.month, 3)
  403. self.assertEqual(n4.day, 30)
  404. n5 = c.get_prev(datetime)
  405. self.assertEqual(n5.month, 3)
  406. self.assertEqual(n5.day, 16)
  407. n6 = c.get_prev(datetime)
  408. self.assertEqual(n6.month, 2)
  409. self.assertEqual(n6.day, 16)
  410. def test_bug34(self):
  411. base = datetime(2012, 2, 24, 0, 0, 0)
  412. itr = croniter('* * 31 2 *', base)
  413. try:
  414. itr.get_next(datetime)
  415. except (CroniterBadDateError,) as ex:
  416. self.assertEqual("{0}".format(ex),
  417. 'failed to find next date')
  418. def testBug57(self):
  419. base = datetime(2012, 2, 24, 0, 0, 0)
  420. itr = croniter('0 4/6 * * *', base)
  421. n1 = itr.get_next(datetime)
  422. self.assertEqual(n1.hour, 4)
  423. self.assertEqual(n1.minute, 0)
  424. self.assertEqual(n1.month, 2)
  425. self.assertEqual(n1.day, 24)
  426. n1 = itr.get_prev(datetime)
  427. self.assertEqual(n1.hour, 22)
  428. self.assertEqual(n1.minute, 0)
  429. self.assertEqual(n1.month, 2)
  430. self.assertEqual(n1.day, 23)
  431. itr = croniter('0 0/6 * * *', base)
  432. n1 = itr.get_next(datetime)
  433. self.assertEqual(n1.hour, 6)
  434. self.assertEqual(n1.minute, 0)
  435. self.assertEqual(n1.month, 2)
  436. self.assertEqual(n1.day, 24)
  437. n1 = itr.get_prev(datetime)
  438. self.assertEqual(n1.hour, 0)
  439. self.assertEqual(n1.minute, 0)
  440. self.assertEqual(n1.month, 2)
  441. self.assertEqual(n1.day, 24)
  442. def test_multiple_months(self):
  443. base = datetime(2016, 3, 1, 0, 0, 0)
  444. itr = croniter('0 0 1 3,6,9,12 *', base)
  445. n1 = itr.get_next(datetime)
  446. self.assertEqual(n1.hour, 0)
  447. self.assertEqual(n1.month, 6)
  448. self.assertEqual(n1.day, 1)
  449. self.assertEqual(n1.year, 2016)
  450. base = datetime(2016, 2, 15, 0, 0, 0)
  451. itr = croniter('0 0 1 3,6,9,12 *', base)
  452. n1 = itr.get_next(datetime)
  453. self.assertEqual(n1.hour, 0)
  454. self.assertEqual(n1.month, 3)
  455. self.assertEqual(n1.day, 1)
  456. self.assertEqual(n1.year, 2016)
  457. base = datetime(2016, 12, 3, 10, 0, 0)
  458. itr = croniter('0 0 1 3,6,9,12 *', base)
  459. n1 = itr.get_next(datetime)
  460. self.assertEqual(n1.hour, 0)
  461. self.assertEqual(n1.month, 3)
  462. self.assertEqual(n1.day, 1)
  463. self.assertEqual(n1.year, 2017)
  464. # The result with this parameters was incorrect.
  465. # self.assertEqual(p1.month, 12
  466. # AssertionError: 9 != 12
  467. base = datetime(2016, 3, 1, 0, 0, 0)
  468. itr = croniter('0 0 1 3,6,9,12 *', base)
  469. p1 = itr.get_prev(datetime)
  470. self.assertEqual(p1.hour, 0)
  471. self.assertEqual(p1.month, 12)
  472. self.assertEqual(p1.day, 1)
  473. self.assertEqual(p1.year, 2015)
  474. # check my change resolves another hidden bug.
  475. base = datetime(2016, 2, 1, 0, 0, 0)
  476. itr = croniter('0 0 1,15,31 * *', base)
  477. p1 = itr.get_prev(datetime)
  478. self.assertEqual(p1.hour, 0)
  479. self.assertEqual(p1.month, 1)
  480. self.assertEqual(p1.day, 31)
  481. self.assertEqual(p1.year, 2016)
  482. base = datetime(2016, 6, 1, 0, 0, 0)
  483. itr = croniter('0 0 1 3,6,9,12 *', base)
  484. p1 = itr.get_prev(datetime)
  485. self.assertEqual(p1.hour, 0)
  486. self.assertEqual(p1.month, 3)
  487. self.assertEqual(p1.day, 1)
  488. self.assertEqual(p1.year, 2016)
  489. base = datetime(2016, 3, 1, 0, 0, 0)
  490. itr = croniter('0 0 1 1,3,6,9,12 *', base)
  491. p1 = itr.get_prev(datetime)
  492. self.assertEqual(p1.hour, 0)
  493. self.assertEqual(p1.month, 1)
  494. self.assertEqual(p1.day, 1)
  495. self.assertEqual(p1.year, 2016)
  496. base = datetime(2016, 3, 1, 0, 0, 0)
  497. itr = croniter('0 0 1 1,3,6,9,12 *', base)
  498. p1 = itr.get_prev(datetime)
  499. self.assertEqual(p1.hour, 0)
  500. self.assertEqual(p1.month, 1)
  501. self.assertEqual(p1.day, 1)
  502. self.assertEqual(p1.year, 2016)
  503. def test_rangeGenerator(self):
  504. base = datetime(2013, 3, 4, 0, 0)
  505. itr = croniter('1-9/2 0 1 * *', base)
  506. n1 = itr.get_next(datetime)
  507. n2 = itr.get_next(datetime)
  508. n3 = itr.get_next(datetime)
  509. n4 = itr.get_next(datetime)
  510. n5 = itr.get_next(datetime)
  511. self.assertEqual(n1.minute, 1)
  512. self.assertEqual(n2.minute, 3)
  513. self.assertEqual(n3.minute, 5)
  514. self.assertEqual(n4.minute, 7)
  515. self.assertEqual(n5.minute, 9)
  516. def testPreviousHour(self):
  517. base = datetime(2012, 6, 23, 17, 41)
  518. itr = croniter('* 10 * * *', base)
  519. prev1 = itr.get_prev(datetime)
  520. self.assertEqual(prev1.year, base.year)
  521. self.assertEqual(prev1.month, base.month)
  522. self.assertEqual(prev1.day, base.day)
  523. self.assertEqual(prev1.hour, 10)
  524. self.assertEqual(prev1.minute, 59)
  525. def testPreviousDay(self):
  526. base = datetime(2012, 6, 27, 0, 15)
  527. itr = croniter('* * 26 * *', base)
  528. prev1 = itr.get_prev(datetime)
  529. self.assertEqual(prev1.year, base.year)
  530. self.assertEqual(prev1.month, base.month)
  531. self.assertEqual(prev1.day, 26)
  532. self.assertEqual(prev1.hour, 23)
  533. self.assertEqual(prev1.minute, 59)
  534. def testPreviousMonth(self):
  535. base = datetime(2012, 6, 18, 0, 15)
  536. itr = croniter('* * * 5 *', base)
  537. prev1 = itr.get_prev(datetime)
  538. self.assertEqual(prev1.year, base.year)
  539. self.assertEqual(prev1.month, 5)
  540. self.assertEqual(prev1.day, 31)
  541. self.assertEqual(prev1.hour, 23)
  542. self.assertEqual(prev1.minute, 59)
  543. def testPreviousDow(self):
  544. base = datetime(2012, 5, 13, 18, 48)
  545. itr = croniter('* * * * sat', base)
  546. prev1 = itr.get_prev(datetime)
  547. self.assertEqual(prev1.year, base.year)
  548. self.assertEqual(prev1.month, base.month)
  549. self.assertEqual(prev1.day, 12)
  550. self.assertEqual(prev1.hour, 23)
  551. self.assertEqual(prev1.minute, 59)
  552. def testGetCurrent(self):
  553. base = datetime(2012, 9, 25, 11, 24)
  554. itr = croniter('* * * * *', base)
  555. res = itr.get_current(datetime)
  556. self.assertEqual(base.year, res.year)
  557. self.assertEqual(base.month, res.month)
  558. self.assertEqual(base.day, res.day)
  559. self.assertEqual(base.hour, res.hour)
  560. self.assertEqual(base.minute, res.minute)
  561. def testTimezone(self):
  562. base = datetime(2013, 3, 4, 12, 15)
  563. itr = croniter('* * * * *', base)
  564. n1 = itr.get_next(datetime)
  565. self.assertEqual(n1.tzinfo, None)
  566. tokyo = pytz.timezone('Asia/Tokyo')
  567. itr2 = croniter('* * * * *', tokyo.localize(base))
  568. n2 = itr2.get_next(datetime)
  569. self.assertEqual(n2.tzinfo.zone, 'Asia/Tokyo')
  570. def testInitNoStartTime(self):
  571. itr = croniter('* * * * *')
  572. sleep(.01)
  573. itr2 = croniter('* * * * *')
  574. # Greater dosnt exists in py26
  575. self.assertTrue(itr2.cur > itr.cur)
  576. def assertScheduleTimezone(self, callback, expected_schedule):
  577. for expected_date, expected_offset in expected_schedule:
  578. d = callback()
  579. self.assertEqual(expected_date, d.replace(tzinfo=None))
  580. self.assertEqual(expected_offset,
  581. croniter._timedelta_to_seconds(d.utcoffset()))
  582. def testTimezoneWinterTime(self):
  583. tz = pytz.timezone('Europe/Athens')
  584. expected_schedule = [
  585. (datetime(2013, 10, 27, 2, 30, 0), 10800),
  586. (datetime(2013, 10, 27, 3, 0, 0), 10800),
  587. (datetime(2013, 10, 27, 3, 30, 0), 10800),
  588. (datetime(2013, 10, 27, 3, 0, 0), 7200),
  589. (datetime(2013, 10, 27, 3, 30, 0), 7200),
  590. (datetime(2013, 10, 27, 4, 0, 0), 7200),
  591. (datetime(2013, 10, 27, 4, 30, 0), 7200),
  592. ]
  593. start = datetime(2013, 10, 27, 2, 0, 0)
  594. ct = croniter('*/30 * * * *', tz.localize(start))
  595. self.assertScheduleTimezone(lambda: ct.get_next(datetime), expected_schedule)
  596. start = datetime(2013, 10, 27, 5, 0, 0)
  597. ct = croniter('*/30 * * * *', tz.localize(start))
  598. self.assertScheduleTimezone(lambda: ct.get_prev(datetime), reversed(expected_schedule))
  599. def testTimezoneSummerTime(self):
  600. tz = pytz.timezone('Europe/Athens')
  601. expected_schedule = [
  602. (datetime(2013, 3, 31, 1, 30, 0), 7200),
  603. (datetime(2013, 3, 31, 2, 0, 0), 7200),
  604. (datetime(2013, 3, 31, 2, 30, 0), 7200),
  605. (datetime(2013, 3, 31, 4, 0, 0), 10800),
  606. (datetime(2013, 3, 31, 4, 30, 0), 10800),
  607. ]
  608. start = datetime(2013, 3, 31, 1, 0, 0)
  609. ct = croniter('*/30 * * * *', tz.localize(start))
  610. self.assertScheduleTimezone(lambda: ct.get_next(datetime), expected_schedule)
  611. start = datetime(2013, 3, 31, 5, 0, 0)
  612. ct = croniter('*/30 * * * *', tz.localize(start))
  613. self.assertScheduleTimezone(lambda: ct.get_prev(datetime), reversed(expected_schedule))
  614. def test_std_dst(self):
  615. """
  616. DST tests
  617. This fixes https://github.com/taichino/croniter/issues/82
  618. """
  619. tz = pytz.timezone('Europe/Warsaw')
  620. # -> 2017-03-26 01:59+1:00 -> 03:00+2:00
  621. local_date = tz.localize(datetime(2017, 3, 26))
  622. val = croniter('0 0 * * *', local_date).get_next(datetime)
  623. self.assertEqual(val, tz.localize(datetime(2017, 3, 27)))
  624. #
  625. local_date = tz.localize(datetime(2017, 3, 26, 1))
  626. cr = croniter('0 * * * *', local_date)
  627. val = cr.get_next(datetime)
  628. self.assertEqual(val, tz.localize(datetime(2017, 3, 26, 3)))
  629. val = cr.get_current(datetime)
  630. self.assertEqual(val, tz.localize(datetime(2017, 3, 26, 3)))
  631. # -> 2017-10-29 02:59+2:00 -> 02:00+1:00
  632. local_date = tz.localize(datetime(2017, 10, 29))
  633. val = croniter('0 0 * * *', local_date).get_next(datetime)
  634. self.assertEqual(val, tz.localize(datetime(2017, 10, 30)))
  635. local_date = tz.localize(datetime(2017, 10, 29, 1, 59))
  636. val = croniter('0 * * * *', local_date).get_next(datetime)
  637. self.assertEqual(
  638. val.replace(tzinfo=None),
  639. tz.localize(datetime(2017, 10, 29, 2)).replace(tzinfo=None))
  640. local_date = tz.localize(datetime(2017, 10, 29, 2))
  641. val = croniter('0 * * * *', local_date).get_next(datetime)
  642. self.assertEqual(val, tz.localize(datetime(2017, 10, 29, 3)))
  643. local_date = tz.localize(datetime(2017, 10, 29, 3))
  644. val = croniter('0 * * * *', local_date).get_next(datetime)
  645. self.assertEqual(val, tz.localize(datetime(2017, 10, 29, 4)))
  646. local_date = tz.localize(datetime(2017, 10, 29, 4))
  647. val = croniter('0 * * * *', local_date).get_next(datetime)
  648. self.assertEqual(val, tz.localize(datetime(2017, 10, 29, 5)))
  649. local_date = tz.localize(datetime(2017, 10, 29, 5))
  650. val = croniter('0 * * * *', local_date).get_next(datetime)
  651. self.assertEqual(val, tz.localize(datetime(2017, 10, 29, 6)))
  652. def test_std_dst2(self):
  653. """
  654. DST tests
  655. This fixes https://github.com/taichino/croniter/issues/87
  656. São Paulo, Brazil: 18/02/2018 00:00 -> 17/02/2018 23:00
  657. """
  658. tz = pytz.timezone("America/Sao_Paulo")
  659. local_dates = [
  660. # 17-22: 00 -> 18-00:00
  661. (tz.localize(datetime(2018, 2, 17, 21, 0, 0)),
  662. '2018-02-18 00:00:00-03:00'),
  663. # 17-23: 00 -> 18-00:00
  664. (tz.localize(datetime(2018, 2, 17, 22, 0, 0)),
  665. '2018-02-18 00:00:00-03:00'),
  666. # 17-23: 00 -> 18-00:00
  667. (tz.localize(datetime(2018, 2, 17, 23, 0, 0)),
  668. '2018-02-18 00:00:00-03:00'),
  669. # 18-00: 00 -> 19-00:00
  670. (tz.localize(datetime(2018, 2, 18, 0, 0, 0)),
  671. '2018-02-19 00:00:00-03:00'),
  672. # 17-22: 00 -> 18-00:00
  673. (tz.localize(datetime(2018, 2, 17, 21, 5, 0)),
  674. '2018-02-18 00:00:00-03:00'),
  675. # 17-23: 00 -> 18-00:00
  676. (tz.localize(datetime(2018, 2, 17, 22, 5, 0)),
  677. '2018-02-18 00:00:00-03:00'),
  678. # 17-23: 00 -> 18-00:00
  679. (tz.localize(datetime(2018, 2, 17, 23, 5, 0)),
  680. '2018-02-18 00:00:00-03:00'),
  681. # 18-00: 00 -> 19-00:00
  682. (tz.localize(datetime(2018, 2, 18, 0, 5, 0)),
  683. '2018-02-19 00:00:00-03:00'),
  684. ]
  685. ret1 = [croniter("0 0 * * *", d[0]).get_next(datetime)
  686. for d in local_dates]
  687. sret1 = ['{0}'.format(d) for d in ret1]
  688. lret1 = ['{0}'.format(d[1]) for d in local_dates]
  689. self.assertEqual(sret1, lret1)
  690. def test_error_alpha_cron(self):
  691. self.assertRaises(CroniterNotAlphaError, croniter.expand,
  692. '* * * janu-jun *')
  693. def test_error_bad_cron(self):
  694. self.assertRaises(CroniterBadCronError, croniter.expand,
  695. '* * * *')
  696. self.assertRaises(CroniterBadCronError, croniter.expand,
  697. '* * * * * * *')
  698. def test_is_valid(self):
  699. self.assertTrue(croniter.is_valid('0 * * * *'))
  700. self.assertFalse(croniter.is_valid('0 * *'))
  701. self.assertFalse(croniter.is_valid('* * * janu-jun *'))
  702. def test_exactly_the_same_minute(self):
  703. base = datetime(2018, 3, 5, 12, 30, 50)
  704. itr = croniter('30 7,12,17 * * *', base)
  705. n1 = itr.get_prev(datetime)
  706. self.assertEqual(12, n1.hour)
  707. n2 = itr.get_prev(datetime)
  708. self.assertEqual(7, n2.hour)
  709. n3 = itr.get_next(datetime)
  710. self.assertEqual(12, n3.hour)
  711. def test_next_when_now_satisfies_cron(self):
  712. ts_a = datetime(2018, 5, 21, 0, 3, 0)
  713. ts_b = datetime(2018, 5, 21, 0, 4, 20)
  714. test_cron = '4 * * * *'
  715. next_a = croniter(test_cron, start_time=ts_a).get_next()
  716. next_b = croniter(test_cron, start_time=ts_b).get_next()
  717. self.assertTrue(next_b > next_a)
  718. def test_milliseconds(self):
  719. """
  720. https://github.com/taichino/croniter/issues/107
  721. """
  722. #
  723. dt = datetime(2018, 1, 2, 10, 0, 0, 500)
  724. c = croniter("0 10 * * * ", start_time=dt)
  725. ts = "{0}".format(datetime.utcfromtimestamp(c.get_prev()))
  726. self.assertEqual(ts, '2018-01-02 10:00:00')
  727. #
  728. dt = datetime(2018, 1, 2, 10, 0, 1, 0)
  729. c = croniter("0 10 * * * ", start_time=dt)
  730. ts = "{0}".format(datetime.utcfromtimestamp(c.get_prev()))
  731. self.assertEqual(ts, '2018-01-02 10:00:00')
  732. #
  733. dt = datetime(2018, 1, 2, 9, 59, 59, 999999)
  734. c = croniter("0 10 * * * ", start_time=dt)
  735. ts = "{0}".format(datetime.utcfromtimestamp(c.get_prev()))
  736. self.assertEqual(ts, '2018-01-01 10:00:00')
  737. if __name__ == '__main__':
  738. unittest.main()