TimeTest.php 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570
  1. <?php
  2. /**
  3. * TimeTest file
  4. *
  5. * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
  6. * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
  7. *
  8. * Licensed under The MIT License
  9. * For full copyright and license information, please see the LICENSE.txt
  10. * Redistributions of files must retain the above copyright notice
  11. *
  12. * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
  13. * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
  14. * @since 1.2.0
  15. * @license http://www.opensource.org/licenses/mit-license.php MIT License
  16. */
  17. namespace Cake\Test\TestCase\Utility;
  18. use Cake\TestSuite\TestCase;
  19. use Cake\Utility\Time;
  20. /**
  21. * TimeTest class
  22. *
  23. */
  24. class TimeTest extends TestCase {
  25. /**
  26. * setUp method
  27. *
  28. * @return void
  29. */
  30. public function setUp() {
  31. parent::setUp();
  32. $this->now = Time::getTestNow();
  33. $this->locale = Time::$defaultLocale;
  34. }
  35. /**
  36. * tearDown method
  37. *
  38. * @return void
  39. */
  40. public function tearDown() {
  41. parent::tearDown();
  42. Time::setTestNow($this->now);
  43. Time::$defaultLocale = $this->locale;
  44. }
  45. /**
  46. * Restored the original system timezone
  47. *
  48. * @return void
  49. */
  50. protected function _restoreSystemTimezone() {
  51. date_default_timezone_set($this->_systemTimezoneIdentifier);
  52. }
  53. /**
  54. * Provides values and expectations for the toQuarter method
  55. *
  56. * @return array
  57. */
  58. public function toQuarterProvider() {
  59. return [
  60. ['2007-12-25', 4],
  61. ['2007-9-25', 3],
  62. ['2007-3-25', 1],
  63. ['2007-3-25', ['2007-01-01', '2007-03-31'], true],
  64. ['2007-5-25', ['2007-04-01', '2007-06-30'], true],
  65. ['2007-8-25', ['2007-07-01', '2007-09-30'], true],
  66. ['2007-12-25', ['2007-10-01', '2007-12-31'], true],
  67. ];
  68. }
  69. /**
  70. * testToQuarter method
  71. *
  72. * @dataProvider toQuarterProvider
  73. * @return void
  74. */
  75. public function testToQuarter($date, $expected, $range = false) {
  76. $this->assertEquals($expected, (new Time($date))->toQuarter($range));
  77. }
  78. /**
  79. * provider for timeAgoInWords() tests
  80. *
  81. * @return array
  82. */
  83. public static function timeAgoProvider() {
  84. return array(
  85. array('-12 seconds', '12 seconds ago'),
  86. array('-12 minutes', '12 minutes ago'),
  87. array('-2 hours', '2 hours ago'),
  88. array('-1 day', '1 day ago'),
  89. array('-2 days', '2 days ago'),
  90. array('-2 days -3 hours', '2 days, 3 hours ago'),
  91. array('-1 week', '1 week ago'),
  92. array('-2 weeks -2 days', '2 weeks, 2 days ago'),
  93. array('+1 week', '1 week'),
  94. array('+1 week 1 day', '1 week, 1 day'),
  95. array('+2 weeks 2 day', '2 weeks, 2 days'),
  96. array('2007-9-24', 'on 24/9/07'),
  97. array('now', 'just now'),
  98. );
  99. }
  100. /**
  101. * testTimeAgoInWords method
  102. *
  103. * @dataProvider timeAgoProvider
  104. * @return void
  105. */
  106. public function testTimeAgoInWords($input, $expected) {
  107. $time = new Time($input);
  108. $result = $time->timeAgoInWords();
  109. $this->assertEquals($expected, $result);
  110. }
  111. /**
  112. * provider for timeAgo with an end date.
  113. *
  114. * @return void
  115. */
  116. public function timeAgoEndProvider() {
  117. return array(
  118. array(
  119. '+4 months +2 weeks +3 days',
  120. '4 months, 2 weeks, 3 days',
  121. '8 years'
  122. ),
  123. array(
  124. '+4 months +2 weeks +1 day',
  125. '4 months, 2 weeks, 1 day',
  126. '8 years'
  127. ),
  128. array(
  129. '+3 months +2 weeks',
  130. '3 months, 2 weeks',
  131. '8 years'
  132. ),
  133. array(
  134. '+3 months +2 weeks +1 day',
  135. '3 months, 2 weeks, 1 day',
  136. '8 years'
  137. ),
  138. array(
  139. '+1 months +1 week +1 day',
  140. '1 month, 1 week, 1 day',
  141. '8 years'
  142. ),
  143. array(
  144. '+2 months +2 days',
  145. '2 months, 2 days',
  146. '+2 months +2 days'
  147. ),
  148. array(
  149. '+2 months +12 days',
  150. '2 months, 1 week, 5 days',
  151. '3 months'
  152. ),
  153. );
  154. }
  155. /**
  156. * test the end option for timeAgoInWords
  157. *
  158. * @dataProvider timeAgoEndProvider
  159. * @return void
  160. */
  161. public function testTimeAgoInWordsEnd($input, $expected, $end) {
  162. $time = new Time($input);
  163. $result = $time->timeAgoInWords(array('end' => $end));
  164. $this->assertEquals($expected, $result);
  165. }
  166. /**
  167. * test the custom string options for timeAgoInWords
  168. *
  169. * @return void
  170. */
  171. public function testTimeAgoInWordsCustomStrings() {
  172. $time = new Time('-8 years -4 months -2 weeks -3 days');
  173. $result = $time->timeAgoInWords(array(
  174. 'relativeString' => 'at least %s ago',
  175. 'accuracy' => array('year' => 'year'),
  176. 'end' => '+10 years'
  177. ));
  178. $expected = 'at least 8 years ago';
  179. $this->assertEquals($expected, $result);
  180. $time = new Time('+4 months +2 weeks +3 days');
  181. $result = $time->timeAgoInWords(array(
  182. 'absoluteString' => 'exactly on %s',
  183. 'accuracy' => array('year' => 'year'),
  184. 'end' => '+2 months'
  185. ));
  186. $expected = 'exactly on ' . date('j/n/y', strtotime('+4 months +2 weeks +3 days'));
  187. $this->assertEquals($expected, $result);
  188. }
  189. /**
  190. * Test the accuracy option for timeAgoInWords()
  191. *
  192. * @return void
  193. */
  194. public function testTimeAgoInWordsAccuracy() {
  195. $time = new Time('+8 years +4 months +2 weeks +3 days');
  196. $result = $time->timeAgoInWords(array(
  197. 'accuracy' => array('year' => 'year'),
  198. 'end' => '+10 years'
  199. ));
  200. $expected = '8 years';
  201. $this->assertEquals($expected, $result);
  202. $time = new Time('+8 years +4 months +2 weeks +3 days');
  203. $result = $time->timeAgoInWords(array(
  204. 'accuracy' => array('year' => 'month'),
  205. 'end' => '+10 years'
  206. ));
  207. $expected = '8 years, 4 months';
  208. $this->assertEquals($expected, $result);
  209. $time = new Time('+8 years +4 months +2 weeks +3 days');
  210. $result = $time->timeAgoInWords(array(
  211. 'accuracy' => array('year' => 'week'),
  212. 'end' => '+10 years'
  213. ));
  214. $expected = '8 years, 4 months, 2 weeks';
  215. $this->assertEquals($expected, $result);
  216. $time = new Time('+8 years +4 months +2 weeks +3 days');
  217. $result = $time->timeAgoInWords(array(
  218. 'accuracy' => array('year' => 'day'),
  219. 'end' => '+10 years'
  220. ));
  221. $expected = '8 years, 4 months, 2 weeks, 3 days';
  222. $this->assertEquals($expected, $result);
  223. $time = new Time('+1 years +5 weeks');
  224. $result = $time->timeAgoInWords(array(
  225. 'accuracy' => array('year' => 'year'),
  226. 'end' => '+10 years'
  227. ));
  228. $expected = '1 year';
  229. $this->assertEquals($expected, $result);
  230. $time = new Time('+58 minutes');
  231. $result = $time->timeAgoInWords(array(
  232. 'accuracy' => 'hour'
  233. ));
  234. $expected = 'in about an hour';
  235. $this->assertEquals($expected, $result);
  236. $time = new Time('+23 hours');
  237. $result = $time->timeAgoInWords(array(
  238. 'accuracy' => 'day'
  239. ));
  240. $expected = 'in about a day';
  241. $this->assertEquals($expected, $result);
  242. }
  243. /**
  244. * Test the format option of timeAgoInWords()
  245. *
  246. * @return void
  247. */
  248. public function testTimeAgoInWordsWithFormat() {
  249. $time = new Time('2007-9-25');
  250. $result = $time->timeAgoInWords(array('format' => 'YYYY-MM-dd'));
  251. $this->assertEquals('on 2007-09-25', $result);
  252. $time = new Time('2007-9-25');
  253. $result = $time->timeAgoInWords(array('format' => 'YYYY-MM-dd'));
  254. $this->assertEquals('on 2007-09-25', $result);
  255. $time = new Time('+2 weeks +2 days');
  256. $result = $time->timeAgoInWords(array('format' => 'YYYY-MM-dd'));
  257. $this->assertRegExp('/^2 weeks, [1|2] day(s)?$/', $result);
  258. $time = new Time('+2 months +2 days');
  259. $result = $time->timeAgoInWords(array('end' => '1 month', 'format' => 'YYYY-MM-dd'));
  260. $this->assertEquals('on ' . date('Y-m-d', strtotime('+2 months +2 days')), $result);
  261. }
  262. /**
  263. * test timeAgoInWords() with negative values.
  264. *
  265. * @return void
  266. */
  267. public function testTimeAgoInWordsNegativeValues() {
  268. $time = new Time('-2 months -2 days');
  269. $result = $time->timeAgoInWords(array('end' => '3 month'));
  270. $this->assertEquals('2 months, 2 days ago', $result);
  271. $time = new Time('-2 months -2 days');
  272. $result = $time->timeAgoInWords(array('end' => '3 month'));
  273. $this->assertEquals('2 months, 2 days ago', $result);
  274. $time = new Time('-2 months -2 days');
  275. $result = $time->timeAgoInWords(array('end' => '1 month', 'format' => 'YYYY-MM-dd'));
  276. $this->assertEquals('on ' . date('Y-m-d', strtotime('-2 months -2 days')), $result);
  277. $time = new Time('-2 years -5 months -2 days');
  278. $result = $time->timeAgoInWords(array('end' => '3 years'));
  279. $this->assertEquals('2 years, 5 months, 2 days ago', $result);
  280. $time = new Time('-2 weeks -2 days');
  281. $result = $time->timeAgoInWords(array('format' => 'YYYY-MM-dd'));
  282. $this->assertEquals('2 weeks, 2 days ago', $result);
  283. $time = new Time('-3 years -12 months');
  284. $result = $time->timeAgoInWords();
  285. $expected = 'on ' . $time->format('j/n/y');
  286. $this->assertEquals($expected, $result);
  287. $time = new Time('-1 month -1 week -6 days');
  288. $result = $time->timeAgoInWords(
  289. array('end' => '1 year', 'accuracy' => array('month' => 'month'))
  290. );
  291. $this->assertEquals('1 month ago', $result);
  292. $time = new Time('-1 years -2 weeks -3 days');
  293. $result = $time->timeAgoInWords(
  294. array('accuracy' => array('year' => 'year'))
  295. );
  296. $expected = 'on ' . $time->format('j/n/y');
  297. $this->assertEquals($expected, $result);
  298. $time = new Time('-13 months -5 days');
  299. $result = $time->timeAgoInWords(array('end' => '2 years'));
  300. $this->assertEquals('1 year, 1 month, 5 days ago', $result);
  301. $time = new Time('-58 minutes');
  302. $result = $time->timeAgoInWords(array('accuracy' => 'hour'));
  303. $this->assertEquals('about an hour ago', $result);
  304. $time = new Time('-23 hours');
  305. $result = $time->timeAgoInWords(array('accuracy' => 'day'));
  306. $this->assertEquals('about a day ago', $result);
  307. }
  308. /**
  309. * testNice method
  310. *
  311. * @return void
  312. */
  313. public function testNice() {
  314. $time = new Time('2014-04-20 20:00', 'UTC');
  315. $this->assertEquals('Apr 20, 2014, 8:00 PM', $time->nice());
  316. $result = $time->nice('America/New_York');
  317. $this->assertEquals('Apr 20, 2014, 4:00 PM', $result);
  318. $this->assertEquals('UTC', $time->getTimezone()->getName());
  319. $this->assertEquals('20 avr. 2014 20:00', $time->nice(null, 'fr-FR'));
  320. $this->assertEquals('20 avr. 2014 16:00', $time->nice('America/New_York', 'fr-FR'));
  321. }
  322. /**
  323. * testToUnix method
  324. *
  325. * @return void
  326. */
  327. public function testToUnix() {
  328. $time = new Time('2014-04-20 08:00:00');
  329. $this->assertEquals('1397980800', $time->toUnixString());
  330. $time = new Time('2021-12-11 07:00:01');
  331. $this->assertEquals('1639206001', $time->toUnixString());
  332. }
  333. /**
  334. * testIsThisWeek method
  335. *
  336. * @return void
  337. */
  338. public function testIsThisWeek() {
  339. $time = new Time('this sunday');
  340. $this->assertTrue($time->isThisWeek());
  341. $this->assertTrue($time->modify('-1 day')->isThisWeek());
  342. $this->assertFalse($time->modify('-6 days')->isThisWeek());
  343. $time = new Time();
  344. $time->year = $time->year - 1;
  345. $this->assertFalse($time->isThisWeek());
  346. }
  347. /**
  348. * testIsThisMonth method
  349. *
  350. * @return void
  351. */
  352. public function testIsThisMonth() {
  353. $time = new Time();
  354. $this->assertTrue($time->isThisMonth());
  355. $time->year = $time->year + 1;
  356. $this->assertFalse($time->isThisMonth());
  357. $time = new Time();
  358. $this->assertFalse($time->modify('next month')->isThisMonth());
  359. }
  360. /**
  361. * testIsThisYear method
  362. *
  363. * @return void
  364. */
  365. public function testIsThisYear() {
  366. $time = new Time();
  367. $this->assertTrue($time->isThisYear());
  368. $time->year = $time->year + 1;
  369. $this->assertFalse($time->isThisYear());
  370. $thisYear = date('Y');
  371. $time = new Time("$thisYear-01-01 00:00", 'Australia/Sydney');
  372. $now = clone $time;
  373. $now->timezone('UTC');
  374. Time::setTestNow($now);
  375. $this->assertFalse($time->isThisYear());
  376. }
  377. /**
  378. * testWasWithinLast method
  379. *
  380. * @return void
  381. */
  382. public function testWasWithinLast() {
  383. $this->assertTrue((new Time('-1 day'))->wasWithinLast('1 day'));
  384. $this->assertTrue((new Time('-1 week'))->wasWithinLast('1 week'));
  385. $this->assertTrue((new Time('-1 year'))->wasWithinLast('1 year'));
  386. $this->assertTrue((new Time('-1 second'))->wasWithinLast('1 second'));
  387. $this->assertTrue((new Time('-1 day'))->wasWithinLast('1 week'));
  388. $this->assertTrue((new Time('-1 week'))->wasWithinLast('2 week'));
  389. $this->assertTrue((new Time('-1 second'))->wasWithinLast('10 minutes'));
  390. $this->assertTrue((new Time('-1 month'))->wasWithinLast('13 month'));
  391. $this->assertTrue((new Time('-1 seconds'))->wasWithinLast('1 hour'));
  392. $this->assertFalse((new Time('-1 year'))->wasWithinLast('1 second'));
  393. $this->assertFalse((new Time('-1 year'))->wasWithinLast('0 year'));
  394. $this->assertFalse((new Time('-1 weeks'))->wasWithinLast('1 day'));
  395. $this->assertTrue((new Time('-3 days'))->wasWithinLast('5'));
  396. }
  397. /**
  398. * testWasWithinLast method
  399. *
  400. * @return void
  401. */
  402. public function testIsWithinNext() {
  403. $this->assertFalse((new Time('-1 day'))->isWithinNext('1 day'));
  404. $this->assertFalse((new Time('-1 week'))->isWithinNext('1 week'));
  405. $this->assertFalse((new Time('-1 year'))->isWithinNext('1 year'));
  406. $this->assertFalse((new Time('-1 second'))->isWithinNext('1 second'));
  407. $this->assertFalse((new Time('-1 day'))->isWithinNext('1 week'));
  408. $this->assertFalse((new Time('-1 week'))->isWithinNext('2 week'));
  409. $this->assertFalse((new Time('-1 second'))->isWithinNext('10 minutes'));
  410. $this->assertFalse((new Time('-1 month'))->isWithinNext('13 month'));
  411. $this->assertFalse((new Time('-1 seconds'))->isWithinNext('1 hour'));
  412. $this->assertTrue((new Time('+1 day'))->isWithinNext('1 day'));
  413. $this->assertTrue((new Time('+1 week'))->isWithinNext('7 day'));
  414. $this->assertTrue((new Time('+1 second'))->isWithinNext('1 minute'));
  415. $this->assertTrue((new Time('+1 month'))->isWithinNext('1 month'));
  416. }
  417. /**
  418. * test formatting dates taking in account preferred i18n locale file
  419. *
  420. * @return void
  421. */
  422. public function testI18nFormat() {
  423. $time = new Time('Thu Jan 14 13:59:28 2010');
  424. $result = $time->i18nFormat();
  425. $expected = '1/14/10, 1:59 PM';
  426. $this->assertEquals($expected, $result);
  427. $result = $time->i18nFormat(\IntlDateFormatter::FULL, null, 'es-ES');
  428. $expected = 'jueves, 14 de enero de 2010, 13:59:28 (GMT)';
  429. $this->assertEquals($expected, $result);
  430. $format = [\IntlDateFormatter::NONE, \IntlDateFormatter::SHORT];
  431. $result = $time->i18nFormat($format);
  432. $expected = '1:59 PM';
  433. $this->assertEquals($expected, $result);
  434. $result = $time->i18nFormat('HH:mm:ss', 'Australia/Sydney');
  435. $expected = '00:59:28';
  436. $this->assertEquals($expected, $result);
  437. Time::$defaultLocale = 'fr-FR';
  438. $result = $time->i18nFormat(\IntlDateFormatter::FULL);
  439. $expected = 'jeudi 14 janvier 2010 13:59:28 UTC';
  440. $this->assertEquals($expected, $result);
  441. $result = $time->i18nFormat(\IntlDateFormatter::FULL, null, 'es-ES');
  442. $expected = 'jueves, 14 de enero de 2010, 13:59:28 (GMT)';
  443. $this->assertEquals($expected, $result, 'DEfault locale should not be used');
  444. }
  445. /**
  446. * testListTimezones
  447. *
  448. * @return void
  449. */
  450. public function testListTimezones() {
  451. $return = Time::listTimezones();
  452. $this->assertTrue(isset($return['Asia']['Asia/Bangkok']));
  453. $this->assertEquals('Bangkok', $return['Asia']['Asia/Bangkok']);
  454. $this->assertTrue(isset($return['America']['America/Argentina/Buenos_Aires']));
  455. $this->assertEquals('Argentina/Buenos_Aires', $return['America']['America/Argentina/Buenos_Aires']);
  456. $this->assertTrue(isset($return['UTC']['UTC']));
  457. $this->assertFalse(isset($return['Cuba']));
  458. $this->assertFalse(isset($return['US']));
  459. $return = Time::listTimezones('#^Asia/#');
  460. $this->assertTrue(isset($return['Asia']['Asia/Bangkok']));
  461. $this->assertFalse(isset($return['Pacific']));
  462. $return = Time::listTimezones('#^(America|Pacific)/#', null, false);
  463. $this->assertTrue(isset($return['America/Argentina/Buenos_Aires']));
  464. $this->assertTrue(isset($return['Pacific/Tahiti']));
  465. $return = Time::listTimezones(\DateTimeZone::ASIA);
  466. $this->assertTrue(isset($return['Asia']['Asia/Bangkok']));
  467. $this->assertFalse(isset($return['Pacific']));
  468. $return = Time::listTimezones(\DateTimeZone::PER_COUNTRY, 'US', false);
  469. $this->assertTrue(isset($return['Pacific/Honolulu']));
  470. $this->assertFalse(isset($return['Asia/Bangkok']));
  471. }
  472. /**
  473. * Tests that __toString uses the i18n formatter
  474. *
  475. * @return void
  476. */
  477. public function testToString() {
  478. $time = new Time('2014-04-20 22:10');
  479. $this->assertEquals('4/20/14, 10:10 PM', (string)$time);
  480. Time::$defaultLocale = 'fr-FR';
  481. $this->assertEquals('20/04/2014 22:10', (string)$time);
  482. }
  483. /**
  484. * Tests diffForHumans
  485. *
  486. * @return void
  487. */
  488. public function testDiffForHumans() {
  489. $time = new Time('2014-04-20 10:10:10');
  490. $other = new Time('2014-04-27 10:10:10');
  491. $this->assertEquals('1 week ago', $time->diffForHumans($other));
  492. $other = new Time('2014-04-21 09:10:10');
  493. $this->assertEquals('23 hours ago', $time->diffForHumans($other));
  494. $other = new Time('2014-04-13 09:10:10');
  495. $this->assertEquals('1 week', $time->diffForHumans($other));
  496. }
  497. }