DateTimeHelperTest.php 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424
  1. <?php
  2. namespace fphammerle\helpers\tests;
  3. use fphammerle\helpers\DateTimeHelper;
  4. class DateTimeHelperTest extends \PHPUnit_Framework_TestCase
  5. {
  6. public function timestampToDateTimeProvider()
  7. {
  8. return [
  9. [null, null],
  10. [0, new \DateTime('1970-01-01 00:00:00', new \DateTimeZone('UTC'))],
  11. [0, new \DateTime('1970-01-01 01:00:00', new \DateTimeZone('Europe/Vienna'))],
  12. [1234567890, new \DateTime('2009-02-13 23:31:30', new \DateTimeZone('UTC'))],
  13. [1234567890, new \DateTime('2009-02-14 00:31:30', new \DateTimeZone('Europe/Vienna'))],
  14. [-3600, new \DateTime('1970-01-01 00:00:00', new \DateTimeZone('Europe/Vienna'))],
  15. ];
  16. }
  17. /**
  18. * @dataProvider timestampToDateTimeProvider
  19. */
  20. public function testTimestampToDateTime($timestamp, $expected_datetime)
  21. {
  22. $generated_datetime = DateTimeHelper::timestampToDateTime($timestamp);
  23. $this->assertEquals($expected_datetime, $generated_datetime);
  24. }
  25. public function timestampToDateTimeDefaultTimezoneProvider()
  26. {
  27. return [
  28. ['UTC', 100],
  29. ['Europe/Vienna', 0],
  30. ['Europe/Vienna', -100],
  31. ['Europe/Vienna', 100],
  32. ['Europe/London', 3600],
  33. ['US/Pacific', 3600],
  34. ];
  35. }
  36. /**
  37. * @dataProvider timestampToDateTimeDefaultTimezoneProvider
  38. */
  39. public function testTimestampToDateTimeDefaultTimezone($timezone, $timestamp)
  40. {
  41. date_default_timezone_set($timezone);
  42. $generated_datetime = DateTimeHelper::timestampToDateTime($timestamp);
  43. $this->assertSame($timestamp, $generated_datetime->getTimestamp());
  44. }
  45. public function parseProvider()
  46. {
  47. return [
  48. // null
  49. [null, 'UTC', null],
  50. [null, 'US/Pacific', null],
  51. // date
  52. ['2016-08-02', 'UTC', new \DatePeriod(
  53. new \DateTime('2016-08-02T00:00:00Z'),
  54. new \DateInterval('P1D'),
  55. new \DateTime('2016-08-03T00:00:00Z')
  56. )],
  57. ['2016-08-02', 'Europe/Vienna', new \DatePeriod(
  58. new \DateTime('2016-08-02T00:00:00+02:00'),
  59. new \DateInterval('P1D'),
  60. new \DateTime('2016-08-03T00:00:00+02:00')
  61. )],
  62. ['2016-08-02', 'Europe/Vienna', new \DatePeriod(
  63. new \DateTime('2016-08-01T22:00:00Z'),
  64. new \DateInterval('P1D'),
  65. new \DateTime('2016-08-02T22:00:00Z')
  66. )],
  67. ['2016-08-02+02:00', 'UTC', new \DatePeriod(
  68. new \DateTime('2016-08-02T00:00:00+02:00'),
  69. new \DateInterval('P1D'),
  70. new \DateTime('2016-08-03T00:00:00+02:00')
  71. )],
  72. ['2016-08-02+02:00', 'UTC', new \DatePeriod(
  73. new \DateTime('2016-08-01T22:00:00Z'),
  74. new \DateInterval('P1D'),
  75. new \DateTime('2016-08-02T22:00:00Z')
  76. )],
  77. // second
  78. ['2016-08-02 15:52:13', 'UTC', new \DatePeriod(
  79. new \DateTime('2016-08-02T15:52:13Z'),
  80. new \DateInterval('PT1S'),
  81. new \DateTime('2016-08-02T15:52:14Z')
  82. )],
  83. ['2016-08-02 15:52:13', 'Europe/Vienna', new \DatePeriod(
  84. new \DateTime('2016-08-02T15:52:13+02:00'),
  85. new \DateInterval('PT1S'),
  86. new \DateTime('2016-08-02T15:52:14+02:00')
  87. )],
  88. ['2016-08-02 15:52:13', 'Europe/Vienna', new \DatePeriod(
  89. new \DateTime('2016-08-02T13:52:13Z'),
  90. new \DateInterval('PT1S'),
  91. new \DateTime('2016-08-02T13:52:14Z')
  92. )],
  93. ['2016-08-02T15:52:13', 'US/Pacific', new \DatePeriod(
  94. new \DateTime('2016-08-02T15:52:13-07:00'),
  95. new \DateInterval('PT1S'),
  96. new \DateTime('2016-08-02T15:52:14-07:00')
  97. )],
  98. ['2016-08-02T15:52:13Z', 'US/Pacific', new \DatePeriod(
  99. new \DateTime('2016-08-02T15:52:13Z'),
  100. new \DateInterval('PT1S'),
  101. new \DateTime('2016-08-02T15:52:14Z')
  102. )],
  103. ['2016-08-02T15:52:13Z', 'Europe/Vienna', new \DatePeriod(
  104. new \DateTime('2016-08-02T17:52:13+02:00'),
  105. new \DateInterval('PT1S'),
  106. new \DateTime('2016-08-02T14:52:14-01:00')
  107. )],
  108. ['2016-08-02T15:52:13+00:00', 'Europe/Vienna', new \DatePeriod(
  109. new \DateTime('2016-08-02T15:52:13Z'),
  110. new \DateInterval('PT1S'),
  111. new \DateTime('2016-08-02T15:52:14Z')
  112. )],
  113. ['2016-08-02T15:52:13+02:00', 'US/Pacific', new \DatePeriod(
  114. new \DateTime('2016-08-02T15:52:13+02:00'),
  115. new \DateInterval('PT1S'),
  116. new \DateTime('2016-08-02T15:52:14+02:00')
  117. )],
  118. ['2016-08-02T15:52:13-08:00', 'UTC', new \DatePeriod(
  119. new \DateTime('2016-08-02T23:52:13Z'),
  120. new \DateInterval('PT1S'),
  121. new \DateTime('2016-08-03T01:52:14+02:00')
  122. )],
  123. ];
  124. }
  125. /**
  126. * @dataProvider parseProvider
  127. */
  128. public function testParse($text, $timezone, $expected)
  129. {
  130. date_default_timezone_set($timezone);
  131. $this->assertEquals($expected, DateTimeHelper::parse($text));
  132. }
  133. public function parseInvalidArgumentProvider()
  134. {
  135. return [
  136. [' '],
  137. [''],
  138. ['2016--12'],
  139. ['2016-10-12 08:20#01'],
  140. [1],
  141. [false],
  142. ];
  143. }
  144. /**
  145. * @dataProvider parseInvalidArgumentProvider
  146. * @expectedException \InvalidArgumentException
  147. */
  148. public function testParseInvalidArgument($text)
  149. {
  150. DateTimeHelper::parse($text);
  151. }
  152. public function parseGetStartProvider()
  153. {
  154. return [
  155. [null, 'UTC', null],
  156. [null, 'US/Pacific', null],
  157. ['2016-08-02', 'UTC', new \DateTime('2016-08-02T00:00:00Z')],
  158. ['2016-08-02', 'Europe/Vienna', new \DateTime('2016-08-02T00:00:00+02:00')],
  159. ['2016-08-02', 'Europe/Vienna', new \DateTime('2016-08-01T22:00:00Z')],
  160. ['2016-08-02 15:52:13', 'UTC', new \DateTime('2016-08-02T15:52:13Z')],
  161. ['2016-08-02 15:52:13', 'Europe/Vienna', new \DateTime('2016-08-02T15:52:13+02:00')],
  162. ['2016-08-02 15:52:13', 'Europe/Vienna', new \DateTime('2016-08-02T13:52:13Z')],
  163. ['2016-08-02T15:52:13', 'US/Pacific', new \DateTime('2016-08-02T15:52:13-07:00')],
  164. ];
  165. }
  166. /**
  167. * @dataProvider parseGetStartProvider
  168. */
  169. public function testParseGetStart($text, $timezone, $expected)
  170. {
  171. date_default_timezone_set($timezone);
  172. $this->assertEquals($expected, DateTimeHelper::parseGetStart($text));
  173. }
  174. public function parseGetStartInvalidArgumentProvider()
  175. {
  176. return [
  177. [' '],
  178. [''],
  179. ['2016--12'],
  180. ['2016-10-12 08:20#01'],
  181. [1],
  182. [false],
  183. ];
  184. }
  185. /**
  186. * @dataProvider parseGetStartInvalidArgumentProvider
  187. * @expectedException \InvalidArgumentException
  188. */
  189. public function testParseGetStartInvalidArgument($text)
  190. {
  191. DateTimeHelper::parseGetStart($text);
  192. }
  193. public function deinvertIntervalProvider()
  194. {
  195. return [
  196. [
  197. \DateInterval::createFromDateString('-2 years'),
  198. ['y' => -2, 'm' => 0, 'd' => 0, 'h' => 0, 'i' => 0, 's' => 0],
  199. ],
  200. [
  201. \DateInterval::createFromDateString('-2 months'),
  202. ['y' => 0, 'm' => -2, 'd' => 0, 'h' => 0, 'i' => 0, 's' => 0],
  203. ],
  204. [
  205. \DateInterval::createFromDateString('-2 days'),
  206. ['y' => 0, 'm' => 0, 'd' => -2, 'h' => 0, 'i' => 0, 's' => 0],
  207. ],
  208. [
  209. \DateInterval::createFromDateString('-2 hours'),
  210. ['y' => 0, 'm' => 0, 'd' => 0, 'h' => -2, 'i' => 0, 's' => 0],
  211. ],
  212. [
  213. \DateInterval::createFromDateString('-2 minutes'),
  214. ['y' => 0, 'm' => 0, 'd' => 0, 'h' => 0, 'i' => -2, 's' => 0],
  215. ],
  216. [
  217. \DateInterval::createFromDateString('-2 seconds'),
  218. ['y' => 0, 'm' => 0, 'd' => 0, 'h' => 0, 'i' => 0, 's' => -2],
  219. ],
  220. [
  221. (new \DateTime('2016-08'))->diff(new \DateTime('2016-07')),
  222. ['y' => 0, 'm' => -1, 'd' => 0, 'h' => 0, 'i' => 0, 's' => 0],
  223. ],
  224. [
  225. (new \DateTime('2016-08-03'))->diff(new \DateTime('2016-07-03')),
  226. ['y' => 0, 'm' => -1, 'd' => 0, 'h' => 0, 'i' => 0, 's' => 0],
  227. ],
  228. [
  229. (new \DateTime('2016-07-03'))->diff(new \DateTime('2016-08-03')),
  230. ['y' => 0, 'm' => 1, 'd' => 0, 'h' => 0, 'i' => 0, 's' => 0],
  231. ],
  232. [
  233. (new \DateTime('2016-08-04'))->diff(new \DateTime('2016-07-03')),
  234. ['y' => 0, 'm' => -1, 'd' => -1, 'h' => 0, 'i' => 0, 's' => 0],
  235. ],
  236. [
  237. (new \DateTime('2016-07-03'))->diff(new \DateTime('2016-08-04')),
  238. ['y' => 0, 'm' => 1, 'd' => 1, 'h' => 0, 'i' => 0, 's' => 0],
  239. ],
  240. [
  241. (new \DateTime('2016-08-02'))->diff(new \DateTime('2016-07-03')),
  242. ['y' => 0, 'm' => 0, 'd' => -30, 'h' => 0, 'i' => 0, 's' => 0],
  243. ],
  244. [
  245. (new \DateTime('2016-07-03'))->diff(new \DateTime('2016-08-02')),
  246. ['y' => 0, 'm' => 0, 'd' => 30, 'h' => 0, 'i' => 0, 's' => 0],
  247. ],
  248. [
  249. (new \DateTime('2016-08-04 18:10:02'))->diff(new \DateTime('2016-07-03 14:13:03')),
  250. ['y' => 0, 'm' => -1, 'd' => -1, 'h' => -3, 'i' => -56, 's' => -59],
  251. ],
  252. [
  253. (new \DateTime('2016-07-03 14:13:03'))->diff(new \DateTime('2016-08-04 18:10:02')),
  254. ['y' => 0, 'm' => 1, 'd' => 1, 'h' => 3, 'i' => 56, 's' => 59],
  255. ],
  256. ];
  257. }
  258. /**
  259. * @dataProvider deinvertIntervalProvider
  260. */
  261. public function testDeinvertInterval($source, $expected_attr)
  262. {
  263. // \DateInterval does not implement clone.
  264. // @see https://bugs.php.net/bug.php?id=50559
  265. $source_copy = unserialize(serialize($source));
  266. $deinverted = DateTimeHelper::deinvertInterval($source_copy);
  267. $this->assertEquals($source, $source_copy);
  268. $this->assertEquals(0, $deinverted->invert);
  269. foreach($expected_attr as $k => $v) {
  270. $this->assertSame($v, $deinverted->$k);
  271. }
  272. }
  273. public function intervalToIsoProvider()
  274. {
  275. return [
  276. [null, null],
  277. ];
  278. }
  279. /**
  280. * @dataProvider intervalToIsoProvider
  281. */
  282. public function testIntervalToIso($interval, $iso)
  283. {
  284. $this->assertSame($iso, DateTimeHelper::intervalToIso($interval));
  285. }
  286. public function intervalToIsoReinitProvider()
  287. {
  288. return [
  289. [new \DateInterval('P1Y')],
  290. [new \DateInterval('P1M')],
  291. [new \DateInterval('P1D')],
  292. [new \DateInterval('PT1H')],
  293. [new \DateInterval('PT1M')],
  294. [new \DateInterval('PT1S')],
  295. [new \DateInterval('P1Y2M3DT4H5M6S')],
  296. ];
  297. }
  298. /**
  299. * @dataProvider intervalToIsoReinitProvider
  300. */
  301. public function testIntervalToIsoReinit($interval)
  302. {
  303. $iso = DateTimeHelper::intervalToIso($interval);
  304. $this->assertEquals($interval, new \DateInterval($iso));
  305. }
  306. public function intervalToIsoReinitUnsupportedProvider()
  307. {
  308. return [
  309. [\DateInterval::createFromDateString('-2 years')],
  310. [\DateInterval::createFromDateString('-2 months')],
  311. [\DateInterval::createFromDateString('-2 days')],
  312. [\DateInterval::createFromDateString('-2 hours')],
  313. [\DateInterval::createFromDateString('-2 minutes')],
  314. [\DateInterval::createFromDateString('-2 seconds')],
  315. [(new \DateTime('2016-08-03'))->diff(new \DateTime('2016-07-03'))],
  316. [(new \DateTime('2016-08-03 10:00:01'))->diff(new \DateTime('2016-08-03 10:00:00'))],
  317. ];
  318. }
  319. /**
  320. * @dataProvider intervalToIsoReinitUnsupportedProvider
  321. * @expectedException \Exception
  322. */
  323. public function testIntervalToIsoReinitUnsupported($interval)
  324. {
  325. DateTimeHelper::intervalToIso($interval);
  326. }
  327. public function periodToIsoProvider()
  328. {
  329. return [
  330. [null, null],
  331. [
  332. new \DatePeriod(
  333. new \DateTime('2016-08-05T14:50:14+08:00'),
  334. new \DateInterval('P1D'),
  335. new \DateTime('2016-08-10T14:50:14+08:00')
  336. ),
  337. 'R4/2016-08-05T14:50:14+08:00/P0Y0M1DT0H0M0S',
  338. ],
  339. [
  340. new \DatePeriod(
  341. new \DateTime('2016-08-05T14:50:14+08:00'),
  342. new \DateInterval('P5D'),
  343. new \DateTime('2016-08-10T14:50:14+08:00')
  344. ),
  345. '2016-08-05T14:50:14+08:00/P0Y0M5DT0H0M0S',
  346. ],
  347. [
  348. new \DatePeriod(
  349. new \DateTime('2016-08-05T14:50:14+08:00'),
  350. new \DateInterval('P1Y2M3DT4H5M6S'),
  351. new \DateTime('2017-10-08T18:55:20+08:00')
  352. ),
  353. '2016-08-05T14:50:14+08:00/P1Y2M3DT4H5M6S',
  354. ],
  355. [
  356. new \DatePeriod(
  357. new \DateTime('2016-08-05T14:50:14Z'),
  358. new \DateInterval('P1D'),
  359. 0
  360. ),
  361. '2016-08-05T14:50:14+00:00/P0Y0M1DT0H0M0S',
  362. ],
  363. [
  364. new \DatePeriod(
  365. new \DateTime('2016-08-05T14:50:14Z'),
  366. new \DateInterval('PT5M'),
  367. 3
  368. ),
  369. 'R3/2016-08-05T14:50:14+00:00/P0Y0M0DT0H5M0S',
  370. ],
  371. [
  372. new \DatePeriod('R3/2016-08-05T14:50:14Z/PT5M'),
  373. 'R3/2016-08-05T14:50:14+00:00/P0Y0M0DT0H5M0S',
  374. ],
  375. [
  376. new \DatePeriod('R4/2016-08-05T14:50:14Z/P1Y2M3DT4H5M6S'),
  377. 'R4/2016-08-05T14:50:14+00:00/P1Y2M3DT4H5M6S',
  378. ],
  379. [
  380. DateTimeHelper::parse('2016-08-05T14:50:14Z'),
  381. '2016-08-05T14:50:14+00:00/P0Y0M0DT0H0M1S',
  382. ],
  383. [
  384. DateTimeHelper::parse('2016-08-05Z'),
  385. '2016-08-05T00:00:00+00:00/P0Y0M1DT0H0M0S',
  386. ],
  387. [
  388. DateTimeHelper::parse('2016-08-05-03:00'),
  389. '2016-08-05T00:00:00-03:00/P0Y0M1DT0H0M0S',
  390. ],
  391. ];
  392. }
  393. /**
  394. * @dataProvider periodToIsoProvider
  395. */
  396. public function testPeriodToIso($period, $iso)
  397. {
  398. $this->assertSame($iso, DateTimeHelper::periodToIso($period));
  399. }
  400. }