TimeTest.php 36 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134
  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\Core\App;
  19. use Cake\Core\Configure;
  20. use Cake\TestSuite\TestCase;
  21. use Cake\Utility\Time;
  22. /**
  23. * TimeTest class
  24. *
  25. */
  26. class TimeTest extends TestCase {
  27. /**
  28. * Default system timezone identifier
  29. *
  30. * @var string
  31. */
  32. protected $_systemTimezoneIdentifier = null;
  33. /**
  34. * setUp method
  35. *
  36. * @return void
  37. */
  38. public function setUp() {
  39. parent::setUp();
  40. $this->Time = new Time();
  41. $this->_systemTimezoneIdentifier = date_default_timezone_get();
  42. Configure::write('Config.language', 'eng');
  43. }
  44. /**
  45. * tearDown method
  46. *
  47. * @return void
  48. */
  49. public function tearDown() {
  50. parent::tearDown();
  51. unset($this->Time);
  52. $this->_restoreSystemTimezone();
  53. }
  54. /**
  55. * Restored the original system timezone
  56. *
  57. * @return void
  58. */
  59. protected function _restoreSystemTimezone() {
  60. date_default_timezone_set($this->_systemTimezoneIdentifier);
  61. }
  62. /**
  63. * Provides values and expectations for the toQuarter method
  64. *
  65. * @return array
  66. */
  67. public function toQuarterProvider() {
  68. return [
  69. ['2007-12-25', 4],
  70. ['2007-9-25', 3],
  71. ['2007-3-25', 1],
  72. ['2007-3-25', ['2007-01-01', '2007-03-31'], true],
  73. ['2007-5-25', ['2007-04-01', '2007-06-30'], true],
  74. ['2007-8-25', ['2007-07-01', '2007-09-30'], true],
  75. ['2007-12-25', ['2007-10-01', '2007-12-31'], true],
  76. ];
  77. }
  78. /**
  79. * testToQuarter method
  80. *
  81. * @dataProvider toQuarterProvider
  82. * @return void
  83. */
  84. public function testToQuarter($date, $expected, $range = false) {
  85. $this->assertEquals($expected, (new Time($date))->toQuarter($range));
  86. }
  87. /**
  88. * provider for timeAgoInWords() tests
  89. *
  90. * @return array
  91. */
  92. public static function timeAgoProvider() {
  93. return array(
  94. array('-12 seconds', '12 seconds ago'),
  95. array('-12 minutes', '12 minutes ago'),
  96. array('-2 hours', '2 hours ago'),
  97. array('-1 day', '1 day ago'),
  98. array('-2 days', '2 days ago'),
  99. array('-2 days -3 hours', '2 days, 3 hours ago'),
  100. array('-1 week', '1 week ago'),
  101. array('-2 weeks -2 days', '2 weeks, 2 days ago'),
  102. array('+1 week', '1 week'),
  103. array('+1 week 1 day', '1 week, 1 day'),
  104. array('+2 weeks 2 day', '2 weeks, 2 days'),
  105. array('2007-9-24', 'on 24/9/07'),
  106. array('now', 'just now'),
  107. );
  108. }
  109. /**
  110. * testTimeAgoInWords method
  111. *
  112. * @dataProvider timeAgoProvider
  113. * @return void
  114. */
  115. public function testTimeAgoInWords($input, $expected) {
  116. $result = $this->Time->timeAgoInWords($input);
  117. $this->assertEquals($expected, $result);
  118. }
  119. /**
  120. * provider for timeAgo with an end date.
  121. *
  122. * @return void
  123. */
  124. public function timeAgoEndProvider() {
  125. return array(
  126. array(
  127. '+4 months +2 weeks +3 days',
  128. '4 months, 2 weeks, 3 days',
  129. '8 years'
  130. ),
  131. array(
  132. '+4 months +2 weeks +1 day',
  133. '4 months, 2 weeks, 1 day',
  134. '8 years'
  135. ),
  136. array(
  137. '+3 months +2 weeks',
  138. '3 months, 2 weeks',
  139. '8 years'
  140. ),
  141. array(
  142. '+3 months +2 weeks +1 day',
  143. '3 months, 2 weeks, 1 day',
  144. '8 years'
  145. ),
  146. array(
  147. '+1 months +1 week +1 day',
  148. '1 month, 1 week, 1 day',
  149. '8 years'
  150. ),
  151. array(
  152. '+2 months +2 days',
  153. '2 months, 2 days',
  154. 'on ' . date('j/n/y', strtotime('+2 months +2 days'))
  155. ),
  156. array(
  157. '+2 months +12 days',
  158. '2 months, 1 week, 5 days',
  159. '3 months'
  160. ),
  161. );
  162. }
  163. /**
  164. * test the end option for timeAgoInWords
  165. *
  166. * @dataProvider timeAgoEndProvider
  167. * @return void
  168. */
  169. public function testTimeAgoInWordsEnd($input, $expected, $end) {
  170. $result = $this->Time->timeAgoInWords(
  171. $input, array('end' => $end)
  172. );
  173. $this->assertEquals($expected, $result);
  174. }
  175. /**
  176. * test the custom string options for timeAgoInWords
  177. *
  178. * @return void
  179. */
  180. public function testTimeAgoInWordsCustomStrings() {
  181. $result = $this->Time->timeAgoInWords(
  182. strtotime('-8 years -4 months -2 weeks -3 days'),
  183. array('relativeString' => 'at least %s ago', 'accuracy' => array('year' => 'year'), 'end' => '+10 years')
  184. );
  185. $expected = 'at least 8 years ago';
  186. $this->assertEquals($expected, $result);
  187. $result = $this->Time->timeAgoInWords(
  188. strtotime('+4 months +2 weeks +3 days'),
  189. array('absoluteString' => 'exactly on %s', 'accuracy' => array('year' => 'year'), 'end' => '+2 months')
  190. );
  191. $expected = 'exactly on ' . date('j/n/y', strtotime('+4 months +2 weeks +3 days'));
  192. $this->assertEquals($expected, $result);
  193. }
  194. /**
  195. * Test the accuracy option for timeAgoInWords()
  196. *
  197. * @return void
  198. */
  199. public function testTimeAgoInWordsAccuracy() {
  200. $result = $this->Time->timeAgoInWords(
  201. strtotime('+8 years +4 months +2 weeks +3 days'),
  202. array('accuracy' => array('year' => 'year'), 'end' => '+10 years')
  203. );
  204. $expected = '8 years';
  205. $this->assertEquals($expected, $result);
  206. $result = $this->Time->timeAgoInWords(
  207. strtotime('+8 years +4 months +2 weeks +3 days'),
  208. array('accuracy' => array('year' => 'month'), 'end' => '+10 years')
  209. );
  210. $expected = '8 years, 4 months';
  211. $this->assertEquals($expected, $result);
  212. $result = $this->Time->timeAgoInWords(
  213. strtotime('+8 years +4 months +2 weeks +3 days'),
  214. array('accuracy' => array('year' => 'week'), 'end' => '+10 years')
  215. );
  216. $expected = '8 years, 4 months, 2 weeks';
  217. $this->assertEquals($expected, $result);
  218. $result = $this->Time->timeAgoInWords(
  219. strtotime('+8 years +4 months +2 weeks +3 days'),
  220. array('accuracy' => array('year' => 'day'), 'end' => '+10 years')
  221. );
  222. $expected = '8 years, 4 months, 2 weeks, 3 days';
  223. $this->assertEquals($expected, $result);
  224. $result = $this->Time->timeAgoInWords(
  225. strtotime('+1 years +5 weeks'),
  226. array('accuracy' => array('year' => 'year'), 'end' => '+10 years')
  227. );
  228. $expected = '1 year';
  229. $this->assertEquals($expected, $result);
  230. $result = $this->Time->timeAgoInWords(
  231. strtotime('+58 minutes'),
  232. array('accuracy' => 'hour')
  233. );
  234. $expected = 'in about an hour';
  235. $this->assertEquals($expected, $result);
  236. $result = $this->Time->timeAgoInWords(
  237. strtotime('+23 hours'),
  238. array('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. $result = $this->Time->timeAgoInWords('2007-9-25', array('format' => 'Y-m-d'));
  250. $this->assertEquals('on 2007-09-25', $result);
  251. $result = $this->Time->timeAgoInWords('2007-9-25', array('format' => 'Y-m-d'));
  252. $this->assertEquals('on 2007-09-25', $result);
  253. $result = $this->Time->timeAgoInWords(
  254. strtotime('+2 weeks +2 days'),
  255. array('format' => 'Y-m-d')
  256. );
  257. $this->assertRegExp('/^2 weeks, [1|2] day(s)?$/', $result);
  258. $result = $this->Time->timeAgoInWords(
  259. strtotime('+2 months +2 days'),
  260. array('end' => '1 month', 'format' => 'Y-m-d')
  261. );
  262. $this->assertEquals('on ' . date('Y-m-d', strtotime('+2 months +2 days')), $result);
  263. }
  264. /**
  265. * test timeAgoInWords() with negative values.
  266. *
  267. * @return void
  268. */
  269. public function testTimeAgoInWordsNegativeValues() {
  270. $result = $this->Time->timeAgoInWords(
  271. strtotime('-2 months -2 days'),
  272. array('end' => '3 month')
  273. );
  274. $this->assertEquals('2 months, 2 days ago', $result);
  275. $result = $this->Time->timeAgoInWords(
  276. strtotime('-2 months -2 days'),
  277. array('end' => '3 month')
  278. );
  279. $this->assertEquals('2 months, 2 days ago', $result);
  280. $result = $this->Time->timeAgoInWords(
  281. strtotime('-2 months -2 days'),
  282. array('end' => '1 month', 'format' => 'Y-m-d')
  283. );
  284. $this->assertEquals('on ' . date('Y-m-d', strtotime('-2 months -2 days')), $result);
  285. $result = $this->Time->timeAgoInWords(
  286. strtotime('-2 years -5 months -2 days'),
  287. array('end' => '3 years')
  288. );
  289. $this->assertEquals('2 years, 5 months, 2 days ago', $result);
  290. $result = $this->Time->timeAgoInWords(
  291. strtotime('-2 weeks -2 days'),
  292. array('format' => 'Y-m-d')
  293. );
  294. $this->assertEquals('2 weeks, 2 days ago', $result);
  295. $time = strtotime('-3 years -12 months');
  296. $result = $this->Time->timeAgoInWords($time);
  297. $expected = 'on ' . date('j/n/y', $time);
  298. $this->assertEquals($expected, $result);
  299. $result = $this->Time->timeAgoInWords(
  300. strtotime('-1 month -1 week -6 days'),
  301. array('end' => '1 year', 'accuracy' => array('month' => 'month'))
  302. );
  303. $this->assertEquals('1 month ago', $result);
  304. $timestamp = strtotime('-1 years -2 weeks -3 days');
  305. $result = $this->Time->timeAgoInWords(
  306. $timestamp,
  307. array('accuracy' => array('year' => 'year'))
  308. );
  309. $expected = 'on ' . date('j/n/y', $timestamp);
  310. $this->assertEquals($expected, $result);
  311. $result = $this->Time->timeAgoInWords(
  312. strtotime('-13 months -5 days'),
  313. array('end' => '2 years')
  314. );
  315. $this->assertEquals('1 year, 1 month, 5 days ago', $result);
  316. $result = $this->Time->timeAgoInWords(
  317. strtotime('-58 minutes'),
  318. array('accuracy' => 'hour')
  319. );
  320. $this->assertEquals('about an hour ago', $result);
  321. $result = $this->Time->timeAgoInWords(
  322. strtotime('-23 hours'),
  323. array('accuracy' => 'day')
  324. );
  325. $this->assertEquals('about a day ago', $result);
  326. }
  327. /**
  328. * testNice method
  329. *
  330. * @return void
  331. */
  332. public function testNice() {
  333. $time = time() + 2 * DAY;
  334. $this->assertEquals(date('D, M jS Y, H:i', $time), $this->Time->nice($time));
  335. $time = time() - 2 * DAY;
  336. $this->assertEquals(date('D, M jS Y, H:i', $time), $this->Time->nice($time));
  337. $time = time();
  338. $this->assertEquals(date('D, M jS Y, H:i', $time), $this->Time->nice($time));
  339. $time = 0;
  340. $this->assertEquals(date('D, M jS Y, H:i', time()), $this->Time->nice($time));
  341. $time = null;
  342. $this->assertEquals(date('D, M jS Y, H:i', time()), $this->Time->nice($time));
  343. $time = time();
  344. $this->assertEquals(date('D', $time), $this->Time->nice($time, null, '%a'));
  345. $this->assertEquals(date('M d, Y', $time), $this->Time->nice($time, null, '%b %d, %Y'));
  346. Time::$niceFormat = '%Y-%d-%m';
  347. $this->assertEquals(date('Y-d-m', $time), $this->Time->nice($time));
  348. $this->assertEquals('%Y-%d-%m', Time::$niceFormat);
  349. Time::$niceFormat = '%Y-%d-%m %H:%M';
  350. $this->assertEquals(date('Y-d-m H:i', $time), $this->Time->nice($time));
  351. $this->assertEquals('%Y-%d-%m %H:%M', Time::$niceFormat);
  352. date_default_timezone_set('UTC');
  353. $result = $this->Time->nice(null, 'America/New_York');
  354. $expected = $this->Time->nice(time(), 'America/New_York');
  355. $this->assertEquals(substr($expected, 0, -1), substr($result, 0, -1));
  356. $this->_restoreSystemTimezone();
  357. }
  358. /**
  359. * testDaysAsSql method
  360. *
  361. * @return void
  362. */
  363. public function testDaysAsSql() {
  364. $begin = time();
  365. $end = time() + DAY;
  366. $field = 'my_field';
  367. $expected = '(my_field >= \'' . date('Y-m-d', $begin) . ' 00:00:00\') AND (my_field <= \'' . date('Y-m-d', $end) . ' 23:59:59\')';
  368. $this->assertEquals($expected, $this->Time->daysAsSql($begin, $end, $field));
  369. }
  370. /**
  371. * testDayAsSql method
  372. *
  373. * @return void
  374. */
  375. public function testDayAsSql() {
  376. $time = time();
  377. $field = 'my_field';
  378. $expected = '(my_field >= \'' . date('Y-m-d', $time) . ' 00:00:00\') AND (my_field <= \'' . date('Y-m-d', $time) . ' 23:59:59\')';
  379. $this->assertEquals($expected, $this->Time->dayAsSql($time, $field));
  380. }
  381. /**
  382. * testToUnix method
  383. *
  384. * @return void
  385. */
  386. public function testToUnix() {
  387. $this->assertEquals(time(), $this->Time->toUnix(time()));
  388. $this->assertEquals(strtotime('+1 day'), $this->Time->toUnix('+1 day'));
  389. $this->assertEquals(strtotime('+0 days'), $this->Time->toUnix('+0 days'));
  390. $this->assertEquals(strtotime('-1 days'), $this->Time->toUnix('-1 days'));
  391. $this->assertEquals(false, $this->Time->toUnix(''));
  392. $this->assertEquals(false, $this->Time->toUnix(null));
  393. }
  394. /**
  395. * testToServer method
  396. *
  397. * @return void
  398. */
  399. public function testToServer() {
  400. date_default_timezone_set('Europe/Paris');
  401. $time = time();
  402. $this->assertEquals(date('Y-m-d H:i:s', $time), $this->Time->toServer($time));
  403. date_default_timezone_set('America/New_York');
  404. $time = time();
  405. date_default_timezone_set('Europe/Paris');
  406. $result = $this->Time->toServer($time, 'America/New_York');
  407. $this->assertEquals(date('Y-m-d H:i:s', $time), $result);
  408. date_default_timezone_set('Europe/Paris');
  409. $time = '2005-10-25 10:00:00';
  410. $result = $this->Time->toServer($time);
  411. $date = new \DateTime($time, new \DateTimeZone('UTC'));
  412. $date->setTimezone(new \DateTimeZone(date_default_timezone_get()));
  413. $expected = $date->format('Y-m-d H:i:s');
  414. $this->assertEquals($expected, $result);
  415. $time = '2002-01-01 05:15:30';
  416. $result = $this->Time->toServer($time, 'America/New_York');
  417. $date = new \DateTime($time, new \DateTimeZone('America/New_York'));
  418. $date->setTimezone(new \DateTimeZone(date_default_timezone_get()));
  419. $expected = $date->format('Y-m-d H:i:s');
  420. $this->assertEquals($expected, $result);
  421. $time = '2010-01-28T15:00:00+10:00';
  422. $result = $this->Time->toServer($time, 'America/New_York');
  423. $date = new \DateTime($time);
  424. $date->setTimezone(new \DateTimeZone(date_default_timezone_get()));
  425. $expected = $date->format('Y-m-d H:i:s');
  426. $this->assertEquals($expected, $result);
  427. $date = new \DateTime(null, new \DateTimeZone('America/New_York'));
  428. $result = $this->Time->toServer($date, 'Pacific/Tahiti');
  429. $date->setTimezone(new \DateTimeZone(date_default_timezone_get()));
  430. $expected = $date->format('Y-m-d H:i:s');
  431. $this->assertEquals($expected, $result);
  432. $this->_restoreSystemTimezone();
  433. $time = time();
  434. $result = $this->Time->toServer($time, null, 'l jS \of F Y h:i:s A');
  435. $expected = date('l jS \of F Y h:i:s A', $time);
  436. $this->assertEquals($expected, $result);
  437. $this->assertFalse($this->Time->toServer(time(), new \stdClass()));
  438. date_default_timezone_set('UTC');
  439. $serverTime = new \DateTime('2012-12-11 14:15:20');
  440. $timezones = array('Europe/London', 'Europe/Brussels', 'UTC', 'America/Denver', 'America/Caracas', 'Asia/Kathmandu');
  441. foreach ($timezones as $timezone) {
  442. $result = $this->Time->toServer($serverTime->format('Y-m-d H:i:s'), $timezone, 'U');
  443. $tz = new \DateTimeZone($timezone);
  444. $this->assertEquals($serverTime->format('U'), $result + $tz->getOffset($serverTime));
  445. }
  446. date_default_timezone_set('UTC');
  447. $date = new \DateTime('now', new \DateTimeZone('America/New_York'));
  448. $result = $this->Time->toServer($date, null, 'Y-m-d H:i:s');
  449. $date->setTimezone($this->Time->timezone());
  450. $expected = $date->format('Y-m-d H:i:s');
  451. $this->assertEquals($expected, $result);
  452. $this->_restoreSystemTimezone();
  453. }
  454. /**
  455. * testToAtom method
  456. *
  457. * @return void
  458. */
  459. public function testToAtom() {
  460. $dateTime = new \DateTime;
  461. $this->assertEquals($dateTime->format($dateTime::ATOM), $this->Time->toAtom($dateTime->getTimestamp()));
  462. }
  463. /**
  464. * testToRss method
  465. *
  466. * @return void
  467. */
  468. public function testToRss() {
  469. $date = '2012-08-12 12:12:45';
  470. $time = strtotime($date);
  471. $this->assertEquals(date('r', $time), $this->Time->toRss($time));
  472. $timezones = array('Europe/London', 'Europe/Brussels', 'UTC', 'America/Denver', 'America/Caracas', 'Asia/Kathmandu');
  473. foreach ($timezones as $timezone) {
  474. $yourTimezone = new \DateTimeZone($timezone);
  475. $yourTime = new \DateTime($date, $yourTimezone);
  476. $userOffset = $yourTimezone->getOffset($yourTime) / HOUR;
  477. $time = $yourTime->format('U');
  478. $this->assertEquals($yourTime->format('r'), $this->Time->toRss($time, $userOffset), "Failed on $timezone");
  479. $this->assertEquals($yourTime->format('r'), $this->Time->toRss($time, $timezone), "Failed on $timezone");
  480. }
  481. }
  482. /**
  483. * testFormat method
  484. *
  485. * @return void
  486. */
  487. public function testFormat() {
  488. $format = 'D-M-Y';
  489. $tz = date_default_timezone_get();
  490. $arr = array(time(), strtotime('+1 days'), strtotime('+1 days'), strtotime('+0 days'));
  491. foreach ($arr as $val) {
  492. $this->assertEquals(date($format, $val), $this->Time->format($format, $val));
  493. $this->assertEquals(date($format, $val), $this->Time->format($format, $val, false, $tz));
  494. }
  495. $result = $this->Time->format('Y-m-d', null, 'never');
  496. $this->assertEquals('never', $result);
  497. $result = $this->Time->format('2012-01-13', '%d-%m-%Y', 'invalid');
  498. $this->assertEquals('13-01-2012', $result);
  499. $result = $this->Time->format('nonsense', '%d-%m-%Y', 'invalid', 'UTC');
  500. $this->assertEquals('invalid', $result);
  501. $result = $this->Time->format('0000-00-00', '%d-%m-%Y', 'invalid');
  502. $this->assertEquals('invalid', $result);
  503. }
  504. /**
  505. * testOfGmt method
  506. *
  507. * @return void
  508. */
  509. public function testGmt() {
  510. $hour = 3;
  511. $min = 4;
  512. $sec = 2;
  513. $month = 5;
  514. $day = 14;
  515. $year = 2007;
  516. $time = mktime($hour, $min, $sec, $month, $day, $year);
  517. $expected = gmmktime($hour, $min, $sec, $month, $day, $year);
  518. $this->assertEquals($expected, $this->Time->gmt(date('Y-n-j G:i:s', $time)));
  519. $hour = date('H');
  520. $min = date('i');
  521. $sec = date('s');
  522. $month = date('m');
  523. $day = date('d');
  524. $year = date('Y');
  525. $expected = gmmktime($hour, $min, $sec, $month, $day, $year);
  526. $this->assertEquals($expected, $this->Time->gmt(null));
  527. }
  528. /**
  529. * testIsToday method
  530. *
  531. * @return void
  532. */
  533. public function testIsToday() {
  534. $result = $this->Time->isToday('+1 day');
  535. $this->assertFalse($result);
  536. $result = $this->Time->isToday('+1 days');
  537. $this->assertFalse($result);
  538. $result = $this->Time->isToday('+0 day');
  539. $this->assertTrue($result);
  540. $result = $this->Time->isToday('-1 day');
  541. $this->assertFalse($result);
  542. }
  543. /**
  544. * testIsFuture method
  545. *
  546. * @return void
  547. */
  548. public function testIsFuture() {
  549. $this->assertTrue($this->Time->isFuture('+1 month'));
  550. $this->assertTrue($this->Time->isFuture('+1 days'));
  551. $this->assertTrue($this->Time->isFuture('+1 minute'));
  552. $this->assertTrue($this->Time->isFuture('+1 second'));
  553. $this->assertFalse($this->Time->isFuture('-1 second'));
  554. $this->assertFalse($this->Time->isFuture('-1 day'));
  555. $this->assertFalse($this->Time->isFuture('-1 week'));
  556. $this->assertFalse($this->Time->isFuture('-1 month'));
  557. }
  558. /**
  559. * testIsPast method
  560. *
  561. * @return void
  562. */
  563. public function testIsPast() {
  564. $this->assertFalse($this->Time->isPast('+1 month'));
  565. $this->assertFalse($this->Time->isPast('+1 days'));
  566. $this->assertFalse($this->Time->isPast('+1 minute'));
  567. $this->assertFalse($this->Time->isPast('+1 second'));
  568. $this->assertTrue($this->Time->isPast('-1 second'));
  569. $this->assertTrue($this->Time->isPast('-1 day'));
  570. $this->assertTrue($this->Time->isPast('-1 week'));
  571. $this->assertTrue($this->Time->isPast('-1 month'));
  572. }
  573. /**
  574. * testIsThisWeek method
  575. *
  576. * @return void
  577. */
  578. public function testIsThisWeek() {
  579. // A map of days which goes from -1 day of week to +1 day of week
  580. $map = array(
  581. 'Mon' => array(-1, 7), 'Tue' => array(-2, 6), 'Wed' => array(-3, 5),
  582. 'Thu' => array(-4, 4), 'Fri' => array(-5, 3), 'Sat' => array(-6, 2),
  583. 'Sun' => array(-7, 1)
  584. );
  585. $days = $map[date('D')];
  586. for ($day = $days[0] + 1; $day < $days[1]; $day++) {
  587. $this->assertTrue($this->Time->isThisWeek(($day > 0 ? '+' : '') . $day . ' days'));
  588. }
  589. $this->assertFalse($this->Time->isThisWeek($days[0] . ' days'));
  590. $this->assertFalse($this->Time->isThisWeek('+' . $days[1] . ' days'));
  591. }
  592. /**
  593. * testIsThisMonth method
  594. *
  595. * @return void
  596. */
  597. public function testIsThisMonth() {
  598. $result = $this->Time->isThisMonth('+0 day');
  599. $this->assertTrue($result);
  600. $result = $this->Time->isThisMonth($time = mktime(0, 0, 0, date('m'), mt_rand(1, 28), date('Y')));
  601. $this->assertTrue($result);
  602. $result = $this->Time->isThisMonth(mktime(0, 0, 0, date('m'), mt_rand(1, 28), date('Y') - mt_rand(1, 12)));
  603. $this->assertFalse($result);
  604. $result = $this->Time->isThisMonth(mktime(0, 0, 0, date('m'), mt_rand(1, 28), date('Y') + mt_rand(1, 12)));
  605. $this->assertFalse($result);
  606. }
  607. /**
  608. * testIsThisYear method
  609. *
  610. * @return void
  611. */
  612. public function testIsThisYear() {
  613. $result = $this->Time->isThisYear('+0 day');
  614. $this->assertTrue($result);
  615. $result = $this->Time->isThisYear(mktime(0, 0, 0, mt_rand(1, 12), mt_rand(1, 28), date('Y')));
  616. $this->assertTrue($result);
  617. }
  618. /**
  619. * testWasYesterday method
  620. *
  621. * @return void
  622. */
  623. public function testWasYesterday() {
  624. $result = $this->Time->wasYesterday('+1 day');
  625. $this->assertFalse($result);
  626. $result = $this->Time->wasYesterday('+1 days');
  627. $this->assertFalse($result);
  628. $result = $this->Time->wasYesterday('+0 day');
  629. $this->assertFalse($result);
  630. $result = $this->Time->wasYesterday('-1 day');
  631. $this->assertTrue($result);
  632. $result = $this->Time->wasYesterday('-1 days');
  633. $this->assertTrue($result);
  634. $result = $this->Time->wasYesterday('-2 days');
  635. $this->assertFalse($result);
  636. }
  637. /**
  638. * testIsTomorrow method
  639. *
  640. * @return void
  641. */
  642. public function testIsTomorrow() {
  643. $result = $this->Time->isTomorrow('+1 day');
  644. $this->assertTrue($result);
  645. $result = $this->Time->isTomorrow('+1 days');
  646. $this->assertTrue($result);
  647. $result = $this->Time->isTomorrow('+0 day');
  648. $this->assertFalse($result);
  649. $result = $this->Time->isTomorrow('-1 day');
  650. $this->assertFalse($result);
  651. }
  652. /**
  653. * testWasWithinLast method
  654. *
  655. * @return void
  656. */
  657. public function testWasWithinLast() {
  658. $this->assertTrue($this->Time->wasWithinLast('1 day', '-1 day'));
  659. $this->assertTrue($this->Time->wasWithinLast('1 week', '-1 week'));
  660. $this->assertTrue($this->Time->wasWithinLast('1 year', '-1 year'));
  661. $this->assertTrue($this->Time->wasWithinLast('1 second', '-1 second'));
  662. $this->assertTrue($this->Time->wasWithinLast('1 minute', '-1 minute'));
  663. $this->assertTrue($this->Time->wasWithinLast('1 year', '-1 year'));
  664. $this->assertTrue($this->Time->wasWithinLast('1 month', '-1 month'));
  665. $this->assertTrue($this->Time->wasWithinLast('1 day', '-1 day'));
  666. $this->assertTrue($this->Time->wasWithinLast('1 week', '-1 day'));
  667. $this->assertTrue($this->Time->wasWithinLast('2 week', '-1 week'));
  668. $this->assertFalse($this->Time->wasWithinLast('1 second', '-1 year'));
  669. $this->assertTrue($this->Time->wasWithinLast('10 minutes', '-1 second'));
  670. $this->assertTrue($this->Time->wasWithinLast('23 minutes', '-1 minute'));
  671. $this->assertFalse($this->Time->wasWithinLast('0 year', '-1 year'));
  672. $this->assertTrue($this->Time->wasWithinLast('13 month', '-1 month'));
  673. $this->assertTrue($this->Time->wasWithinLast('2 days', '-1 day'));
  674. $this->assertFalse($this->Time->wasWithinLast('1 week', '-2 weeks'));
  675. $this->assertFalse($this->Time->wasWithinLast('1 second', '-2 seconds'));
  676. $this->assertFalse($this->Time->wasWithinLast('1 day', '-2 days'));
  677. $this->assertFalse($this->Time->wasWithinLast('1 hour', '-2 hours'));
  678. $this->assertFalse($this->Time->wasWithinLast('1 month', '-2 months'));
  679. $this->assertFalse($this->Time->wasWithinLast('1 year', '-2 years'));
  680. $this->assertFalse($this->Time->wasWithinLast('1 day', '-2 weeks'));
  681. $this->assertFalse($this->Time->wasWithinLast('1 day', '-2 days'));
  682. $this->assertFalse($this->Time->wasWithinLast('0 days', '-2 days'));
  683. $this->assertTrue($this->Time->wasWithinLast('1 hour', '-20 seconds'));
  684. $this->assertTrue($this->Time->wasWithinLast('1 year', '-60 minutes -30 seconds'));
  685. $this->assertTrue($this->Time->wasWithinLast('3 years', '-2 months'));
  686. $this->assertTrue($this->Time->wasWithinLast('5 months', '-4 months'));
  687. $this->assertTrue($this->Time->wasWithinLast('5 ', '-3 days'));
  688. $this->assertTrue($this->Time->wasWithinLast('1 ', '-1 hour'));
  689. $this->assertTrue($this->Time->wasWithinLast('1 ', '-1 minute'));
  690. $this->assertTrue($this->Time->wasWithinLast('1 ', '-23 hours -59 minutes -59 seconds'));
  691. }
  692. /**
  693. * testWasWithinLast method
  694. *
  695. * @return void
  696. */
  697. public function testIsWithinNext() {
  698. $this->assertFalse($this->Time->isWithinNext('1 day', '-1 day'));
  699. $this->assertFalse($this->Time->isWithinNext('1 week', '-1 week'));
  700. $this->assertFalse($this->Time->isWithinNext('1 year', '-1 year'));
  701. $this->assertFalse($this->Time->isWithinNext('1 second', '-1 second'));
  702. $this->assertFalse($this->Time->isWithinNext('1 minute', '-1 minute'));
  703. $this->assertFalse($this->Time->isWithinNext('1 year', '-1 year'));
  704. $this->assertFalse($this->Time->isWithinNext('1 month', '-1 month'));
  705. $this->assertFalse($this->Time->isWithinNext('1 day', '-1 day'));
  706. $this->assertFalse($this->Time->isWithinNext('1 week', '-1 day'));
  707. $this->assertFalse($this->Time->isWithinNext('2 week', '-1 week'));
  708. $this->assertFalse($this->Time->isWithinNext('1 second', '-1 year'));
  709. $this->assertFalse($this->Time->isWithinNext('10 minutes', '-1 second'));
  710. $this->assertFalse($this->Time->isWithinNext('23 minutes', '-1 minute'));
  711. $this->assertFalse($this->Time->isWithinNext('0 year', '-1 year'));
  712. $this->assertFalse($this->Time->isWithinNext('13 month', '-1 month'));
  713. $this->assertFalse($this->Time->isWithinNext('2 days', '-1 day'));
  714. $this->assertFalse($this->Time->isWithinNext('1 week', '-2 weeks'));
  715. $this->assertFalse($this->Time->isWithinNext('1 second', '-2 seconds'));
  716. $this->assertFalse($this->Time->isWithinNext('1 day', '-2 days'));
  717. $this->assertFalse($this->Time->isWithinNext('1 hour', '-2 hours'));
  718. $this->assertFalse($this->Time->isWithinNext('1 month', '-2 months'));
  719. $this->assertFalse($this->Time->isWithinNext('1 year', '-2 years'));
  720. $this->assertFalse($this->Time->isWithinNext('1 day', '-2 weeks'));
  721. $this->assertFalse($this->Time->isWithinNext('1 day', '-2 days'));
  722. $this->assertFalse($this->Time->isWithinNext('0 days', '-2 days'));
  723. $this->assertFalse($this->Time->isWithinNext('1 hour', '-20 seconds'));
  724. $this->assertFalse($this->Time->isWithinNext('1 year', '-60 minutes -30 seconds'));
  725. $this->assertFalse($this->Time->isWithinNext('3 years', '-2 months'));
  726. $this->assertFalse($this->Time->isWithinNext('5 months', '-4 months'));
  727. $this->assertFalse($this->Time->isWithinNext('5 ', '-3 days'));
  728. $this->assertFalse($this->Time->isWithinNext('1 ', '-1 hour'));
  729. $this->assertFalse($this->Time->isWithinNext('1 ', '-1 minute'));
  730. $this->assertFalse($this->Time->isWithinNext('1 ', '-23 hours -59 minutes -59 seconds'));
  731. $this->assertTrue($this->Time->isWithinNext('7 days', '6 days, 23 hours, 59 minutes, 59 seconds'));
  732. $this->assertFalse($this->Time->isWithinNext('7 days', '6 days, 23 hours, 59 minutes, 61 seconds'));
  733. }
  734. /**
  735. * testUserOffset method
  736. *
  737. * @return void
  738. */
  739. public function testUserOffset() {
  740. $timezoneServer = new \DateTimeZone(date_default_timezone_get());
  741. $timeServer = new \DateTime('now', $timezoneServer);
  742. $yourTimezone = $timezoneServer->getOffset($timeServer) / HOUR;
  743. $expected = time();
  744. $result = $this->Time->fromString(time(), $yourTimezone);
  745. $this->assertWithinMargin($expected, $result, 1);
  746. $result = $this->Time->fromString(time(), $timezoneServer->getName());
  747. $this->assertWithinMargin($expected, $result, 1);
  748. $result = $this->Time->fromString(time(), $timezoneServer);
  749. $this->assertWithinMargin($expected, $result, 1);
  750. Configure::write('Config.timezone', $timezoneServer->getName());
  751. $result = $this->Time->fromString(time());
  752. $this->assertWithinMargin($expected, $result, 1);
  753. Configure::delete('Config.timezone');
  754. }
  755. /**
  756. * test fromString()
  757. *
  758. * @return void
  759. */
  760. public function testFromString() {
  761. $result = $this->Time->fromString('');
  762. $this->assertFalse($result);
  763. $result = $this->Time->fromString(0, 0);
  764. $this->assertFalse($result);
  765. $result = $this->Time->fromString('+1 hour');
  766. $expected = strtotime('+1 hour');
  767. $this->assertWithinMargin($expected, $result, 1);
  768. $timezone = date('Z', time());
  769. $result = $this->Time->fromString('+1 hour', $timezone);
  770. $expected = $this->Time->convert(strtotime('+1 hour'), $timezone);
  771. $this->assertWithinMargin($expected, $result, 1);
  772. $timezone = date_default_timezone_get();
  773. $result = $this->Time->fromString('+1 hour', $timezone);
  774. $expected = $this->Time->convert(strtotime('+1 hour'), $timezone);
  775. $this->assertWithinMargin($expected, $result, 1);
  776. date_default_timezone_set('UTC');
  777. $date = new \DateTime('now', new \DateTimeZone('Europe/London'));
  778. $this->Time->fromString($date);
  779. $this->assertEquals('Europe/London', $date->getTimeZone()->getName());
  780. $this->_restoreSystemTimezone();
  781. }
  782. /**
  783. * test fromString() with a DateTime object as the dateString
  784. *
  785. * @return void
  786. */
  787. public function testFromStringWithDateTime() {
  788. date_default_timezone_set('UTC');
  789. $date = new \DateTime('+1 hour', new \DateTimeZone('America/New_York'));
  790. $result = $this->Time->fromString($date, 'UTC');
  791. $date->setTimezone(new \DateTimeZone('UTC'));
  792. $expected = $date->format('U') + $date->getOffset();
  793. $this->assertWithinMargin($expected, $result, 1);
  794. date_default_timezone_set('Australia/Melbourne');
  795. $date = new \DateTime('+1 hour', new \DateTimeZone('America/New_York'));
  796. $result = $this->Time->fromString($date, 'Asia/Kuwait');
  797. $date->setTimezone(new \DateTimeZone('Asia/Kuwait'));
  798. $expected = $date->format('U') + $date->getOffset();
  799. $this->assertWithinMargin($expected, $result, 1);
  800. $this->_restoreSystemTimezone();
  801. }
  802. /**
  803. * Test that datetimes in the default timezone are not modified.
  804. *
  805. * @return void
  806. */
  807. public function testFromStringWithDateTimeNoConversion() {
  808. Configure::write('Config.timezone', date_default_timezone_get());
  809. $date = new \DateTime('2013-04-09');
  810. $result = $this->Time->fromString($date);
  811. $this->assertEquals($result, $date->format('U'));
  812. }
  813. /**
  814. * test converting time specifiers using a time definition localfe file
  815. *
  816. * @return void
  817. */
  818. public function testConvertSpecifiers() {
  819. Configure::write('Config.language', 'es');
  820. $time = strtotime('Thu Jan 14 11:43:39 2010');
  821. $result = $this->Time->convertSpecifiers('%a', $time);
  822. $expected = 'jue';
  823. $this->assertEquals($expected, $result);
  824. $result = $this->Time->convertSpecifiers('%A', $time);
  825. $expected = 'jueves';
  826. $this->assertEquals($expected, $result);
  827. $result = $this->Time->convertSpecifiers('%c', $time);
  828. $expected = 'jue %d ene %Y %H:%M:%S %Z';
  829. $this->assertEquals($expected, $result);
  830. $result = $this->Time->convertSpecifiers('%C', $time);
  831. $expected = '20';
  832. $this->assertEquals($expected, $result);
  833. $result = $this->Time->convertSpecifiers('%D', $time);
  834. $expected = '%m/%d/%y';
  835. $this->assertEquals($expected, $result);
  836. $result = $this->Time->convertSpecifiers('%b', $time);
  837. $expected = 'ene';
  838. $this->assertEquals($expected, $result);
  839. $result = $this->Time->convertSpecifiers('%h', $time);
  840. $expected = 'ene';
  841. $this->assertEquals($expected, $result);
  842. $result = $this->Time->convertSpecifiers('%B', $time);
  843. $expected = 'enero';
  844. $this->assertEquals($expected, $result);
  845. $result = $this->Time->convertSpecifiers('%n', $time);
  846. $expected = "\n";
  847. $this->assertEquals($expected, $result);
  848. $result = $this->Time->convertSpecifiers('%n', $time);
  849. $expected = "\n";
  850. $this->assertEquals($expected, $result);
  851. $result = $this->Time->convertSpecifiers('%p', $time);
  852. $expected = 'AM';
  853. $this->assertEquals($expected, $result);
  854. $result = $this->Time->convertSpecifiers('%P', $time);
  855. $expected = 'am';
  856. $this->assertEquals($expected, $result);
  857. $result = $this->Time->convertSpecifiers('%r', $time);
  858. $expected = '%I:%M:%S AM';
  859. $this->assertEquals($expected, $result);
  860. $result = $this->Time->convertSpecifiers('%R', $time);
  861. $expected = '11:43';
  862. $this->assertEquals($expected, $result);
  863. $result = $this->Time->convertSpecifiers('%t', $time);
  864. $expected = "\t";
  865. $this->assertEquals($expected, $result);
  866. $result = $this->Time->convertSpecifiers('%T', $time);
  867. $expected = '%H:%M:%S';
  868. $this->assertEquals($expected, $result);
  869. $result = $this->Time->convertSpecifiers('%u', $time);
  870. $expected = 4;
  871. $this->assertEquals($expected, $result);
  872. $result = $this->Time->convertSpecifiers('%x', $time);
  873. $expected = '%d/%m/%y';
  874. $this->assertEquals($expected, $result);
  875. $result = $this->Time->convertSpecifiers('%X', $time);
  876. $expected = '%H:%M:%S';
  877. $this->assertEquals($expected, $result);
  878. }
  879. /**
  880. * test convert %e on windows.
  881. *
  882. * @return void
  883. */
  884. public function testConvertPercentE() {
  885. $this->skipIf(DIRECTORY_SEPARATOR !== '\\', 'Cannot run windows tests on non-windows OS.');
  886. $time = strtotime('Thu Jan 14 11:43:39 2010');
  887. $result = $this->Time->convertSpecifiers('%e', $time);
  888. $expected = '14';
  889. $this->assertEquals($expected, $result);
  890. $result = $this->Time->convertSpecifiers('%e', strtotime('2011-01-01'));
  891. $expected = ' 1';
  892. $this->assertEquals($expected, $result);
  893. }
  894. /**
  895. * test formatting dates taking in account preferred i18n locale file
  896. *
  897. * @return void
  898. */
  899. public function testI18nFormat() {
  900. Configure::write('Config.language', 'es');
  901. $time = strtotime('Thu Jan 14 13:59:28 2010');
  902. $result = $this->Time->i18nFormat($time);
  903. $expected = '14/01/10';
  904. $this->assertEquals($expected, $result);
  905. $result = $this->Time->i18nFormat($time, '%c');
  906. $expected = 'jue 14 ene 2010 13:59:28 ' . utf8_encode(strftime('%Z', $time));
  907. $this->assertEquals($expected, $result);
  908. $result = $this->Time->i18nFormat($time, 'Time is %r, and date is %x');
  909. $expected = 'Time is 01:59:28 PM, and date is 14/01/10';
  910. $this->assertEquals($expected, $result);
  911. $time = strtotime('Wed Jan 13 13:59:28 2010');
  912. $result = $this->Time->i18nFormat($time);
  913. $expected = '13/01/10';
  914. $this->assertEquals($expected, $result);
  915. $result = $this->Time->i18nFormat($time, '%c');
  916. $expected = 'mié 13 ene 2010 13:59:28 ' . utf8_encode(strftime('%Z', $time));
  917. $this->assertEquals($expected, $result);
  918. $result = $this->Time->i18nFormat($time, 'Time is %r, and date is %x');
  919. $expected = 'Time is 01:59:28 PM, and date is 13/01/10';
  920. $this->assertEquals($expected, $result);
  921. $result = $this->Time->i18nFormat('invalid date', '%x', 'Date invalid');
  922. $expected = 'Date invalid';
  923. $this->assertEquals($expected, $result);
  924. }
  925. /**
  926. * test new format() syntax which inverts first and second parameters
  927. *
  928. * @return void
  929. */
  930. public function testFormatNewSyntax() {
  931. $time = time();
  932. $this->assertEquals($this->Time->format($time), $this->Time->i18nFormat($time));
  933. $this->assertEquals($this->Time->format($time, '%c'), $this->Time->i18nFormat($time, '%c'));
  934. }
  935. /**
  936. * testListTimezones
  937. *
  938. * @return void
  939. */
  940. public function testListTimezones() {
  941. $return = Time::listTimezones();
  942. $this->assertTrue(isset($return['Asia']['Asia/Bangkok']));
  943. $this->assertEquals('Bangkok', $return['Asia']['Asia/Bangkok']);
  944. $this->assertTrue(isset($return['America']['America/Argentina/Buenos_Aires']));
  945. $this->assertEquals('Argentina/Buenos_Aires', $return['America']['America/Argentina/Buenos_Aires']);
  946. $this->assertTrue(isset($return['UTC']['UTC']));
  947. $this->assertFalse(isset($return['Cuba']));
  948. $this->assertFalse(isset($return['US']));
  949. $return = Time::listTimezones('#^Asia/#');
  950. $this->assertTrue(isset($return['Asia']['Asia/Bangkok']));
  951. $this->assertFalse(isset($return['Pacific']));
  952. $return = Time::listTimezones('#^(America|Pacific)/#', null, false);
  953. $this->assertTrue(isset($return['America/Argentina/Buenos_Aires']));
  954. $this->assertTrue(isset($return['Pacific/Tahiti']));
  955. $return = Time::listTimezones(\DateTimeZone::ASIA);
  956. $this->assertTrue(isset($return['Asia']['Asia/Bangkok']));
  957. $this->assertFalse(isset($return['Pacific']));
  958. $return = Time::listTimezones(\DateTimeZone::PER_COUNTRY, 'US', false);
  959. $this->assertTrue(isset($return['Pacific/Honolulu']));
  960. $this->assertFalse(isset($return['Asia/Bangkok']));
  961. }
  962. /**
  963. * Tests that using Cake\Utility\Time::format() with the correct sytax actually converts
  964. * from one timezone to the other correctly
  965. *
  966. * @return void
  967. */
  968. public function testCorrectTimezoneConversion() {
  969. date_default_timezone_set('UTC');
  970. $date = '2012-01-01 10:00:00';
  971. $converted = Time::format($date, '%Y-%m-%d %H:%M', '', 'Europe/Copenhagen');
  972. $expected = new \DateTime($date);
  973. $expected->setTimezone(new \DateTimeZone('Europe/Copenhagen'));
  974. $this->assertEquals($expected->format('Y-m-d H:i'), $converted);
  975. }
  976. }