]> git.immae.eu Git - github/wallabag/wallabag.git/blob - vendor/symfony/intl/Symfony/Component/Intl/Tests/DateFormatter/AbstractIntlDateFormatterTest.php
3ffb49092a1b40aafe972600cf54fd604ecdeeb1
[github/wallabag/wallabag.git] / vendor / symfony / intl / Symfony / Component / Intl / Tests / DateFormatter / AbstractIntlDateFormatterTest.php
1 <?php
2
3 /*
4 * This file is part of the Symfony package.
5 *
6 * (c) Fabien Potencier <fabien@symfony.com>
7 *
8 * For the full copyright and license information, please view the LICENSE
9 * file that was distributed with this source code.
10 */
11
12 namespace Symfony\Component\Intl\Tests\DateFormatter;
13
14 use Symfony\Component\Intl\DateFormatter\IntlDateFormatter;
15 use Symfony\Component\Intl\Globals\IntlGlobals;
16 use Symfony\Component\Intl\Intl;
17
18 /**
19 * Test case for IntlDateFormatter implementations.
20 *
21 * @author Bernhard Schussek <bschussek@gmail.com>
22 */
23 abstract class AbstractIntlDateFormatterTest extends \PHPUnit_Framework_TestCase
24 {
25 /**
26 * When a time zone is not specified, it uses the system default however it returns null in the getter method
27 * @covers Symfony\Component\Intl\DateFormatter\IntlDateFormatter::getTimeZoneId
28 * @see StubIntlDateFormatterTest::testDefaultTimeZoneIntl()
29 */
30 public function testConstructorDefaultTimeZone()
31 {
32 $formatter = $this->getDateFormatter('en', IntlDateFormatter::MEDIUM, IntlDateFormatter::SHORT);
33
34 // In PHP 5.5 default timezone depends on `date_default_timezone_get()` method
35 if (version_compare(PHP_VERSION, '5.5.0-dev', '>=')) {
36 $this->assertEquals(date_default_timezone_get(), $formatter->getTimeZoneId());
37 } else {
38 $this->assertNull($formatter->getTimeZoneId());
39 }
40 }
41
42 /**
43 * @dataProvider formatProvider
44 */
45 public function testFormat($pattern, $timestamp, $expected)
46 {
47 $errorCode = IntlGlobals::U_ZERO_ERROR;
48 $errorMessage = 'U_ZERO_ERROR';
49
50 $formatter = $this->getDefaultDateFormatter($pattern);
51 $this->assertSame($expected, $formatter->format($timestamp));
52 $this->assertIsIntlSuccess($formatter, $errorMessage, $errorCode);
53 }
54
55 public function formatProvider()
56 {
57 $formatData = array(
58 /* general */
59 array('y-M-d', 0, '1970-1-1'),
60 array("EEE, MMM d, ''yy", 0, "Thu, Jan 1, '70"),
61 array('h:mm a', 0, '12:00 AM'),
62 array('yyyyy.MMMM.dd hh:mm aaa', 0, '01970.January.01 12:00 AM'),
63
64 /* escaping */
65 array("'M'", 0, 'M'),
66 array("'yy'", 0, 'yy'),
67 array("'''yy'", 0, "'yy"),
68 array("''y", 0, "'1970"),
69 array("''yy", 0, "'70"),
70 array("H 'o'' clock'", 0, "0 o' clock"),
71
72 /* month */
73 array('M', 0, '1'),
74 array('MM', 0, '01'),
75 array('MMM', 0, 'Jan'),
76 array('MMMM', 0, 'January'),
77 array('MMMMM', 0, 'J'),
78 array('MMMMMM', 0, '000001'),
79
80 array('L', 0, '1'),
81 array('LL', 0, '01'),
82 array('LLL', 0, 'Jan'),
83 array('LLLL', 0, 'January'),
84 array('LLLLL', 0, 'J'),
85 array('LLLLLL', 0, '000001'),
86
87 /* year */
88 array('y', 0, '1970'),
89 array('yy', 0, '70'),
90 array('yyy', 0, '1970'),
91 array('yyyy', 0, '1970'),
92 array('yyyyy', 0, '01970'),
93 array('yyyyyy', 0, '001970'),
94
95 /* day */
96 array('d', 0, '1'),
97 array('dd', 0, '01'),
98 array('ddd', 0, '001'),
99
100 /* quarter */
101 array('Q', 0, '1'),
102 array('QQ', 0, '01'),
103 array('QQQ', 0, 'Q1'),
104 array('QQQQ', 0, '1st quarter'),
105 array('QQQQQ', 0, '1st quarter'),
106
107 array('q', 0, '1'),
108 array('qq', 0, '01'),
109 array('qqq', 0, 'Q1'),
110 array('qqqq', 0, '1st quarter'),
111 array('qqqqq', 0, '1st quarter'),
112
113 // 4 months
114 array('Q', 7776000, '2'),
115 array('QQ', 7776000, '02'),
116 array('QQQ', 7776000, 'Q2'),
117 array('QQQQ', 7776000, '2nd quarter'),
118
119 // 7 months
120 array('QQQQ', 15638400, '3rd quarter'),
121
122 // 10 months
123 array('QQQQ', 23587200, '4th quarter'),
124
125 /* 12-hour (1-12) */
126 array('h', 0, '12'),
127 array('hh', 0, '12'),
128 array('hhh', 0, '012'),
129
130 array('h', 1, '12'),
131 array('h', 3600, '1'),
132 array('h', 43200, '12'), // 12 hours
133
134 /* day of year */
135 array('D', 0, '1'),
136 array('D', 86400, '2'), // 1 day
137 array('D', 31536000, '1'), // 1 year
138 array('D', 31622400, '2'), // 1 year + 1 day
139
140 /* day of week */
141 array('E', 0, 'Thu'),
142 array('EE', 0, 'Thu'),
143 array('EEE', 0, 'Thu'),
144 array('EEEE', 0, 'Thursday'),
145 array('EEEEE', 0, 'T'),
146 array('EEEEEE', 0, 'Thu'),
147
148 array('E', 1296540000, 'Tue'), // 2011-02-01
149 array('E', 1296950400, 'Sun'), // 2011-02-06
150
151 /* am/pm marker */
152 array('a', 0, 'AM'),
153 array('aa', 0, 'AM'),
154 array('aaa', 0, 'AM'),
155 array('aaaa', 0, 'AM'),
156
157 // 12 hours
158 array('a', 43200, 'PM'),
159 array('aa', 43200, 'PM'),
160 array('aaa', 43200, 'PM'),
161 array('aaaa', 43200, 'PM'),
162
163 /* 24-hour (0-23) */
164 array('H', 0, '0'),
165 array('HH', 0, '00'),
166 array('HHH', 0, '000'),
167
168 array('H', 1, '0'),
169 array('H', 3600, '1'),
170 array('H', 43200, '12'),
171 array('H', 46800, '13'),
172
173 /* 24-hour (1-24) */
174 array('k', 0, '24'),
175 array('kk', 0, '24'),
176 array('kkk', 0, '024'),
177
178 array('k', 1, '24'),
179 array('k', 3600, '1'),
180 array('k', 43200, '12'),
181 array('k', 46800, '13'),
182
183 /* 12-hour (0-11) */
184 array('K', 0, '0'),
185 array('KK', 0, '00'),
186 array('KKK', 0, '000'),
187
188 array('K', 1, '0'),
189 array('K', 3600, '1'),
190 array('K', 43200, '0'), // 12 hours
191
192 /* minute */
193 array('m', 0, '0'),
194 array('mm', 0, '00'),
195 array('mmm', 0, '000'),
196
197 array('m', 1, '0'),
198 array('m', 60, '1'),
199 array('m', 120, '2'),
200 array('m', 180, '3'),
201 array('m', 3600, '0'),
202 array('m', 3660, '1'),
203 array('m', 43200, '0'), // 12 hours
204
205 /* second */
206 array('s', 0, '0'),
207 array('ss', 0, '00'),
208 array('sss', 0, '000'),
209
210 array('s', 1, '1'),
211 array('s', 2, '2'),
212 array('s', 5, '5'),
213 array('s', 30, '30'),
214 array('s', 59, '59'),
215 array('s', 60, '0'),
216 array('s', 120, '0'),
217 array('s', 180, '0'),
218 array('s', 3600, '0'),
219 array('s', 3601, '1'),
220 array('s', 3630, '30'),
221 array('s', 43200, '0'), // 12 hours
222
223 // general
224 array("yyyy.MM.dd 'at' HH:mm:ss zzz", 0, '1970.01.01 at 00:00:00 GMT'),
225 array('K:mm a, z', 0, '0:00 AM, GMT'),
226
227 // timezone
228 array('z', 0, 'GMT'),
229 array('zz', 0, 'GMT'),
230 array('zzz', 0, 'GMT'),
231 array('zzzz', 0, 'GMT'),
232 array('zzzzz', 0, 'GMT'),
233 );
234
235 // As of PHP 5.3.4, IntlDateFormatter::format() accepts DateTime instances
236 if (version_compare(PHP_VERSION, '5.3.4', '>=')) {
237 $dateTime = new \DateTime('@0');
238
239 /* general, DateTime */
240 $formatData[] = array('y-M-d', $dateTime, '1970-1-1');
241 $formatData[] = array("EEE, MMM d, ''yy", $dateTime, "Thu, Jan 1, '70");
242 $formatData[] = array('h:mm a', $dateTime, '12:00 AM');
243 $formatData[] = array('yyyyy.MMMM.dd hh:mm aaa', $dateTime, '01970.January.01 12:00 AM');
244
245 $formatData[] = array("yyyy.MM.dd 'at' HH:mm:ss zzz", $dateTime, '1970.01.01 at 00:00:00 GMT');
246 $formatData[] = array('K:mm a, z', $dateTime, '0:00 AM, GMT');
247 }
248
249 return $formatData;
250 }
251
252 /**
253 * @dataProvider formatErrorProvider
254 */
255 public function testFormatIllegalArgumentError($pattern, $timestamp, $errorMessage)
256 {
257 $errorCode = IntlGlobals::U_ILLEGAL_ARGUMENT_ERROR;
258
259 $formatter = $this->getDefaultDateFormatter($pattern);
260 $this->assertFalse($formatter->format($timestamp));
261 $this->assertIsIntlFailure($formatter, $errorMessage, $errorCode);
262 }
263
264 public function formatErrorProvider()
265 {
266 // With PHP 5.5 IntlDateFormatter accepts empty values ('0')
267 if (version_compare(PHP_VERSION, '5.5.0-dev', '>=')) {
268 return array(
269 array('y-M-d', 'foobar', 'datefmt_format: string \'foobar\' is not numeric, which would be required for it to be a valid date: U_ILLEGAL_ARGUMENT_ERROR')
270 );
271 }
272
273 $message = 'datefmt_format: takes either an array or an integer timestamp value : U_ILLEGAL_ARGUMENT_ERROR';
274
275 if (version_compare(PHP_VERSION, '5.3.4', '>=')) {
276 $message = 'datefmt_format: takes either an array or an integer timestamp value or a DateTime object: U_ILLEGAL_ARGUMENT_ERROR';
277 }
278
279 return array(
280 array('y-M-d', '0', $message),
281 array('y-M-d', 'foobar', $message),
282 );
283 }
284
285 /**
286 * @dataProvider formatWithTimezoneProvider
287 */
288 public function testFormatWithTimezone($timestamp, $timezone, $expected)
289 {
290 $pattern = 'yyyy-MM-dd HH:mm:ss';
291 $formatter = $this->getDateFormatter('en', IntlDateFormatter::MEDIUM, IntlDateFormatter::SHORT, $timezone, IntlDateFormatter::GREGORIAN, $pattern);
292 $this->assertSame($expected, $formatter->format($timestamp));
293 }
294
295 public function formatWithTimezoneProvider()
296 {
297 $data = array(
298 array(0, 'UTC', '1970-01-01 00:00:00'),
299 array(0, 'GMT', '1970-01-01 00:00:00'),
300 array(0, 'GMT-03:00', '1969-12-31 21:00:00'),
301 array(0, 'GMT+03:00', '1970-01-01 03:00:00'),
302 array(0, 'Europe/Zurich', '1970-01-01 01:00:00'),
303 array(0, 'Europe/Paris', '1970-01-01 01:00:00'),
304 array(0, 'Africa/Cairo', '1970-01-01 02:00:00'),
305 array(0, 'Africa/Casablanca', '1970-01-01 00:00:00'),
306 array(0, 'Africa/Djibouti', '1970-01-01 03:00:00'),
307 array(0, 'Africa/Johannesburg', '1970-01-01 02:00:00'),
308 array(0, 'America/Antigua', '1969-12-31 20:00:00'),
309 array(0, 'America/Toronto', '1969-12-31 19:00:00'),
310 array(0, 'America/Vancouver', '1969-12-31 16:00:00'),
311 array(0, 'Asia/Aqtau', '1970-01-01 05:00:00'),
312 array(0, 'Asia/Bangkok', '1970-01-01 07:00:00'),
313 array(0, 'Asia/Dubai', '1970-01-01 04:00:00'),
314 array(0, 'Australia/Brisbane', '1970-01-01 10:00:00'),
315 array(0, 'Australia/Eucla', '1970-01-01 08:45:00'),
316 array(0, 'Australia/Melbourne', '1970-01-01 10:00:00'),
317 array(0, 'Europe/Berlin', '1970-01-01 01:00:00'),
318 array(0, 'Europe/Dublin', '1970-01-01 01:00:00'),
319 array(0, 'Europe/Warsaw', '1970-01-01 01:00:00'),
320 array(0, 'Pacific/Fiji', '1970-01-01 12:00:00'),
321 );
322
323 // As of PHP 5.5, intl ext no longer fallbacks invalid time zones to UTC
324 if (!version_compare(PHP_VERSION, '5.5.0-dev', '>=')) {
325 // When time zone not exists, uses UTC by default
326 $data[] = array(0, 'Foo/Bar', '1970-01-01 00:00:00');
327 $data[] = array(0, 'UTC+04:30', '1970-01-01 00:00:00');
328 $data[] = array(0, 'UTC+04:AA', '1970-01-01 00:00:00');
329 }
330
331 return $data;
332 }
333
334 public function testFormatWithGmtTimezone()
335 {
336 $formatter = $this->getDefaultDateFormatter('zzzz');
337
338 if (version_compare(PHP_VERSION, '5.5.0-dev', '>=')) {
339 $formatter->setTimeZone('GMT+03:00');
340 } else {
341 $formatter->setTimeZoneId('GMT+03:00');
342 }
343
344 $this->assertEquals('GMT+03:00', $formatter->format(0));
345 }
346
347 public function testFormatWithGmtTimeZoneAndMinutesOffset()
348 {
349 $formatter = $this->getDefaultDateFormatter('zzzz');
350
351 if (version_compare(PHP_VERSION, '5.5.0-dev', '>=')) {
352 $formatter->setTimeZone('GMT+00:30');
353 } else {
354 $formatter->setTimeZoneId('GMT+00:30');
355 }
356
357 $this->assertEquals('GMT+00:30', $formatter->format(0));
358 }
359
360 public function testFormatWithNonStandardTimezone()
361 {
362 $formatter = $this->getDefaultDateFormatter('zzzz');
363
364 if (version_compare(PHP_VERSION, '5.5.0-dev', '>=')) {
365 $formatter->setTimeZone('Pacific/Fiji');
366 } else {
367 $formatter->setTimeZoneId('Pacific/Fiji');
368 }
369
370 $this->assertEquals('Fiji Standard Time', $formatter->format(0));
371 }
372
373 public function testFormatWithConstructorTimezone()
374 {
375 $formatter = $this->getDateFormatter('en', IntlDateFormatter::MEDIUM, IntlDateFormatter::SHORT, 'UTC');
376 $formatter->setPattern('yyyy-MM-dd HH:mm:ss');
377
378 $this->assertEquals(
379 $this->getDateTime(0)->format('Y-m-d H:i:s'),
380 $formatter->format(0)
381 );
382 }
383
384 public function testFormatWithTimezoneFromEnvironmentVariable()
385 {
386 if (version_compare(PHP_VERSION, '5.5.0-dev', '>=')) {
387 $this->markTestSkipped('IntlDateFormatter in PHP 5.5 no longer depends on TZ environment.');
388 }
389
390 $tz = getenv('TZ');
391 putenv('TZ=Europe/London');
392
393 $formatter = $this->getDateFormatter('en', IntlDateFormatter::MEDIUM, IntlDateFormatter::SHORT);
394 $formatter->setPattern('yyyy-MM-dd HH:mm:ss');
395
396 $this->assertEquals(
397 $this->getDateTime(0)->format('Y-m-d H:i:s'),
398 $formatter->format(0)
399 );
400
401 $this->assertEquals('Europe/London', getenv('TZ'));
402
403 // Restores TZ.
404 putenv('TZ='.$tz);
405 }
406
407 public function testFormatWithTimezoneFromPhp()
408 {
409 if (!version_compare(PHP_VERSION, '5.5.0-dev', '>=')) {
410 $this->markTestSkipped('Only in PHP 5.5 IntlDateFormatter depends on default timezone (`date_default_timezone_get()`).');
411 }
412
413 $tz = date_default_timezone_get();
414 date_default_timezone_set('Europe/London');
415
416 $formatter = $this->getDateFormatter('en', IntlDateFormatter::MEDIUM, IntlDateFormatter::SHORT);
417 $formatter->setPattern('yyyy-MM-dd HH:mm:ss');
418
419 $this->assertEquals(
420 $this->getDateTime(0)->format('Y-m-d H:i:s'),
421 $formatter->format(0)
422 );
423
424 $this->assertEquals('Europe/London', date_default_timezone_get());
425
426 // Restores TZ.
427 date_default_timezone_set($tz);
428 }
429
430 /**
431 * @dataProvider dateAndTimeTypeProvider
432 */
433 public function testDateAndTimeType($timestamp, $datetype, $timetype, $expected)
434 {
435 $formatter = $this->getDateFormatter('en', $datetype, $timetype, 'UTC');
436 $this->assertSame($expected, $formatter->format($timestamp));
437 }
438
439 public function dateAndTimeTypeProvider()
440 {
441 return array(
442 array(0, IntlDateFormatter::FULL, IntlDateFormatter::NONE, 'Thursday, January 1, 1970'),
443 array(0, IntlDateFormatter::LONG, IntlDateFormatter::NONE, 'January 1, 1970'),
444 array(0, IntlDateFormatter::MEDIUM, IntlDateFormatter::NONE, 'Jan 1, 1970'),
445 array(0, IntlDateFormatter::SHORT, IntlDateFormatter::NONE, '1/1/70'),
446 array(0, IntlDateFormatter::NONE, IntlDateFormatter::FULL, '12:00:00 AM GMT'),
447 array(0, IntlDateFormatter::NONE, IntlDateFormatter::LONG, '12:00:00 AM GMT'),
448 array(0, IntlDateFormatter::NONE, IntlDateFormatter::MEDIUM, '12:00:00 AM'),
449 array(0, IntlDateFormatter::NONE, IntlDateFormatter::SHORT, '12:00 AM'),
450 );
451 }
452
453 public function testGetCalendar()
454 {
455 $formatter = $this->getDefaultDateFormatter();
456 $this->assertEquals(IntlDateFormatter::GREGORIAN, $formatter->getCalendar());
457 }
458
459 public function testGetDateType()
460 {
461 $formatter = $this->getDateFormatter('en', IntlDateFormatter::FULL, IntlDateFormatter::NONE);
462 $this->assertEquals(IntlDateFormatter::FULL, $formatter->getDateType());
463 }
464
465 public function testGetLocale()
466 {
467 $formatter = $this->getDefaultDateFormatter();
468 $this->assertEquals('en', $formatter->getLocale());
469 }
470
471 public function testGetPattern()
472 {
473 $formatter = $this->getDateFormatter('en', IntlDateFormatter::FULL, IntlDateFormatter::NONE, 'UTC', IntlDateFormatter::GREGORIAN, 'yyyy-MM-dd');
474 $this->assertEquals('yyyy-MM-dd', $formatter->getPattern());
475 }
476
477 public function testGetTimeType()
478 {
479 $formatter = $this->getDateFormatter('en', IntlDateFormatter::NONE, IntlDateFormatter::FULL);
480 $this->assertEquals(IntlDateFormatter::FULL, $formatter->getTimeType());
481 }
482
483 /**
484 * @dataProvider parseProvider
485 */
486 public function testParse($pattern, $value, $expected)
487 {
488 $errorCode = IntlGlobals::U_ZERO_ERROR;
489 $errorMessage = 'U_ZERO_ERROR';
490
491 $formatter = $this->getDefaultDateFormatter($pattern);
492 $this->assertSame($expected, $formatter->parse($value));
493 $this->assertIsIntlSuccess($formatter, $errorMessage, $errorCode);
494 }
495
496 public function parseProvider()
497 {
498 return array_merge(
499 $this->parseYearProvider(),
500 $this->parseQuarterProvider(),
501 $this->parseMonthProvider(),
502 $this->parseStandaloneMonthProvider(),
503 $this->parseDayProvider(),
504 $this->parseDayOfWeekProvider(),
505 $this->parseDayOfYearProvider(),
506 $this->parseHour12ClockOneBasedProvider(),
507 $this->parseHour12ClockZeroBasedProvider(),
508 $this->parseHour24ClockOneBasedProvider(),
509 $this->parseHour24ClockZeroBasedProvider(),
510 $this->parseMinuteProvider(),
511 $this->parseSecondProvider(),
512 $this->parseTimezoneProvider(),
513 $this->parseAmPmProvider(),
514 $this->parseStandaloneAmPmProvider(),
515 $this->parseRegexMetaCharsProvider(),
516 $this->parseQuoteCharsProvider(),
517 $this->parseDashSlashProvider()
518 );
519 }
520
521 public function parseYearProvider()
522 {
523 return array(
524 array('y-M-d', '1970-1-1', 0),
525 array('yy-M-d', '70-1-1', 0),
526 );
527 }
528
529 public function parseQuarterProvider()
530 {
531 return array(
532 array('Q', '1', 0),
533 array('QQ', '01', 0),
534 array('QQQ', 'Q1', 0),
535 array('QQQQ', '1st quarter', 0),
536 array('QQQQQ', '1st quarter', 0),
537
538 array('Q', '2', 7776000),
539 array('QQ', '02', 7776000),
540 array('QQQ', 'Q2', 7776000),
541 array('QQQQ', '2nd quarter', 7776000),
542 array('QQQQQ', '2nd quarter', 7776000),
543
544 array('q', '1', 0),
545 array('qq', '01', 0),
546 array('qqq', 'Q1', 0),
547 array('qqqq', '1st quarter', 0),
548 array('qqqqq', '1st quarter', 0),
549 );
550 }
551
552 public function parseMonthProvider()
553 {
554 return array(
555 array('y-M-d', '1970-1-1', 0),
556 array('y-MMM-d', '1970-Jan-1', 0),
557 array('y-MMMM-d', '1970-January-1', 0),
558 );
559 }
560
561 public function parseStandaloneMonthProvider()
562 {
563 return array(
564 array('y-L-d', '1970-1-1', 0),
565 array('y-LLL-d', '1970-Jan-1', 0),
566 array('y-LLLL-d', '1970-January-1', 0),
567 );
568 }
569
570 public function parseDayProvider()
571 {
572 return array(
573 array('y-M-d', '1970-1-1', 0),
574 array('y-M-dd', '1970-1-01', 0),
575 array('y-M-ddd', '1970-1-001', 0),
576 );
577 }
578
579 public function parseDayOfWeekProvider()
580 {
581 return array(
582 array('E', 'Thu', 0),
583 array('EE', 'Thu', 0),
584 array('EEE', 'Thu', 0),
585 array('EEEE', 'Thursday', 0),
586 array('EEEEE', 'T', 432000),
587 array('EEEEEE', 'Thu', 0),
588 );
589 }
590
591 public function parseDayOfYearProvider()
592 {
593 return array(
594 array('D', '1', 0),
595 array('D', '2', 86400),
596 );
597 }
598
599 public function parseHour12ClockOneBasedProvider()
600 {
601 return array(
602 // 12 hours (1-12)
603 array('y-M-d h', '1970-1-1 1', 3600),
604 array('y-M-d h', '1970-1-1 10', 36000),
605 array('y-M-d hh', '1970-1-1 11', 39600),
606 array('y-M-d hh', '1970-1-1 12', 0),
607 array('y-M-d hh a', '1970-1-1 0 AM', 0),
608 array('y-M-d hh a', '1970-1-1 1 AM', 3600),
609 array('y-M-d hh a', '1970-1-1 10 AM', 36000),
610 array('y-M-d hh a', '1970-1-1 11 AM', 39600),
611 array('y-M-d hh a', '1970-1-1 12 AM', 0),
612 array('y-M-d hh a', '1970-1-1 23 AM', 82800),
613 array('y-M-d hh a', '1970-1-1 24 AM', 86400),
614 array('y-M-d hh a', '1970-1-1 0 PM', 43200),
615 array('y-M-d hh a', '1970-1-1 1 PM', 46800),
616 array('y-M-d hh a', '1970-1-1 10 PM', 79200),
617 array('y-M-d hh a', '1970-1-1 11 PM', 82800),
618 array('y-M-d hh a', '1970-1-1 12 PM', 43200),
619 array('y-M-d hh a', '1970-1-1 23 PM', 126000),
620 array('y-M-d hh a', '1970-1-1 24 PM', 129600),
621 );
622 }
623
624 public function parseHour12ClockZeroBasedProvider()
625 {
626 return array(
627 // 12 hours (0-11)
628 array('y-M-d K', '1970-1-1 1', 3600),
629 array('y-M-d K', '1970-1-1 10', 36000),
630 array('y-M-d KK', '1970-1-1 11', 39600),
631 array('y-M-d KK', '1970-1-1 12', 43200),
632 array('y-M-d KK a', '1970-1-1 0 AM', 0),
633 array('y-M-d KK a', '1970-1-1 1 AM', 3600),
634 array('y-M-d KK a', '1970-1-1 10 AM', 36000),
635 array('y-M-d KK a', '1970-1-1 11 AM', 39600),
636 array('y-M-d KK a', '1970-1-1 12 AM', 43200),
637 array('y-M-d KK a', '1970-1-1 23 AM', 82800),
638 array('y-M-d KK a', '1970-1-1 24 AM', 86400),
639 array('y-M-d KK a', '1970-1-1 0 PM', 43200),
640 array('y-M-d KK a', '1970-1-1 1 PM', 46800),
641 array('y-M-d KK a', '1970-1-1 10 PM', 79200),
642 array('y-M-d KK a', '1970-1-1 11 PM', 82800),
643 array('y-M-d KK a', '1970-1-1 12 PM', 86400),
644 array('y-M-d KK a', '1970-1-1 23 PM', 126000),
645 array('y-M-d KK a', '1970-1-1 24 PM', 129600),
646 );
647 }
648
649 public function parseHour24ClockOneBasedProvider()
650 {
651 return array(
652 // 24 hours (1-24)
653 array('y-M-d k', '1970-1-1 1', 3600),
654 array('y-M-d k', '1970-1-1 10', 36000),
655 array('y-M-d kk', '1970-1-1 11', 39600),
656 array('y-M-d kk', '1970-1-1 12', 43200),
657 array('y-M-d kk', '1970-1-1 23', 82800),
658 array('y-M-d kk', '1970-1-1 24', 0),
659 array('y-M-d kk a', '1970-1-1 0 AM', 0),
660 array('y-M-d kk a', '1970-1-1 1 AM', 0),
661 array('y-M-d kk a', '1970-1-1 10 AM', 0),
662 array('y-M-d kk a', '1970-1-1 11 AM', 0),
663 array('y-M-d kk a', '1970-1-1 12 AM', 0),
664 array('y-M-d kk a', '1970-1-1 23 AM', 0),
665 array('y-M-d kk a', '1970-1-1 24 AM', 0),
666 array('y-M-d kk a', '1970-1-1 0 PM', 43200),
667 array('y-M-d kk a', '1970-1-1 1 PM', 43200),
668 array('y-M-d kk a', '1970-1-1 10 PM', 43200),
669 array('y-M-d kk a', '1970-1-1 11 PM', 43200),
670 array('y-M-d kk a', '1970-1-1 12 PM', 43200),
671 array('y-M-d kk a', '1970-1-1 23 PM', 43200),
672 array('y-M-d kk a', '1970-1-1 24 PM', 43200),
673 );
674 }
675
676 public function parseHour24ClockZeroBasedProvider()
677 {
678 return array(
679 // 24 hours (0-23)
680 array('y-M-d H', '1970-1-1 0', 0),
681 array('y-M-d H', '1970-1-1 1', 3600),
682 array('y-M-d H', '1970-1-1 10', 36000),
683 array('y-M-d HH', '1970-1-1 11', 39600),
684 array('y-M-d HH', '1970-1-1 12', 43200),
685 array('y-M-d HH', '1970-1-1 23', 82800),
686 array('y-M-d HH a', '1970-1-1 0 AM', 0),
687 array('y-M-d HH a', '1970-1-1 1 AM', 0),
688 array('y-M-d HH a', '1970-1-1 10 AM', 0),
689 array('y-M-d HH a', '1970-1-1 11 AM', 0),
690 array('y-M-d HH a', '1970-1-1 12 AM', 0),
691 array('y-M-d HH a', '1970-1-1 23 AM', 0),
692 array('y-M-d HH a', '1970-1-1 24 AM', 0),
693 array('y-M-d HH a', '1970-1-1 0 PM', 43200),
694 array('y-M-d HH a', '1970-1-1 1 PM', 43200),
695 array('y-M-d HH a', '1970-1-1 10 PM', 43200),
696 array('y-M-d HH a', '1970-1-1 11 PM', 43200),
697 array('y-M-d HH a', '1970-1-1 12 PM', 43200),
698 array('y-M-d HH a', '1970-1-1 23 PM', 43200),
699 array('y-M-d HH a', '1970-1-1 24 PM', 43200),
700 );
701 }
702
703 public function parseMinuteProvider()
704 {
705 return array(
706 array('y-M-d HH:m', '1970-1-1 0:1', 60),
707 array('y-M-d HH:mm', '1970-1-1 0:10', 600),
708 );
709 }
710
711 public function parseSecondProvider()
712 {
713 return array(
714 array('y-M-d HH:mm:s', '1970-1-1 00:01:1', 61),
715 array('y-M-d HH:mm:ss', '1970-1-1 00:01:10', 70),
716 );
717 }
718
719 public function parseTimezoneProvider()
720 {
721 return array(
722 array('y-M-d HH:mm:ss zzzz', '1970-1-1 00:00:00 GMT-03:00', 10800),
723 array('y-M-d HH:mm:ss zzzz', '1970-1-1 00:00:00 GMT-04:00', 14400),
724 array('y-M-d HH:mm:ss zzzz', '1970-1-1 00:00:00 GMT-00:00', 0),
725 array('y-M-d HH:mm:ss zzzz', '1970-1-1 00:00:00 GMT+03:00', -10800),
726 array('y-M-d HH:mm:ss zzzz', '1970-1-1 00:00:00 GMT+04:00', -14400),
727 array('y-M-d HH:mm:ss zzzz', '1970-1-1 00:00:00 GMT-0300', 10800),
728 array('y-M-d HH:mm:ss zzzz', '1970-1-1 00:00:00 GMT+0300', -10800),
729
730 // a previous timezone parsing should not change the timezone for the next parsing
731 array('y-M-d HH:mm:ss', '1970-1-1 00:00:00', 0),
732 );
733 }
734
735 public function parseAmPmProvider()
736 {
737 return array(
738 // AM/PM (already covered by hours tests)
739 array('y-M-d HH:mm:ss a', '1970-1-1 00:00:00 AM', 0),
740 array('y-M-d HH:mm:ss a', '1970-1-1 00:00:00 PM', 43200),
741 );
742 }
743
744 public function parseStandaloneAmPmProvider()
745 {
746 return array(
747 array('a', 'AM', 0),
748 array('a', 'PM', 43200),
749 );
750 }
751
752 public function parseRegexMetaCharsProvider()
753 {
754 return array(
755 // regexp meta chars in the pattern string
756 array('y[M-d', '1970[1-1', 0),
757 array('y[M/d', '1970[1/1', 0),
758 );
759 }
760
761 public function parseQuoteCharsProvider()
762 {
763 return array(
764 array("'M'", 'M', 0),
765 array("'yy'", 'yy', 0),
766 array("'''yy'", "'yy", 0),
767 array("''y", "'1970", 0),
768 array("H 'o'' clock'", "0 o' clock", 0),
769 );
770 }
771
772 public function parseDashSlashProvider()
773 {
774 return array(
775 array('y-M-d', '1970/1/1', 0),
776 array('yy-M-d', '70/1/1', 0),
777 array('y/M/d', '1970-1-1', 0),
778 array('yy/M/d', '70-1-1', 0),
779 );
780 }
781
782 /**
783 * @dataProvider parseErrorProvider
784 */
785 public function testParseError($pattern, $value)
786 {
787 $errorCode = IntlGlobals::U_PARSE_ERROR;
788 $errorMessage = 'Date parsing failed: U_PARSE_ERROR';
789
790 $formatter = $this->getDefaultDateFormatter($pattern);
791 $this->assertFalse($formatter->parse($value));
792 $this->assertIsIntlFailure($formatter, $errorMessage, $errorCode);
793 }
794
795 public function parseErrorProvider()
796 {
797 return array(
798 // 1 char month
799 array('y-MMMMM-d', '1970-J-1'),
800 array('y-MMMMM-d', '1970-S-1'),
801
802 // standalone 1 char month
803 array('y-LLLLL-d', '1970-J-1'),
804 array('y-LLLLL-d', '1970-S-1'),
805 );
806 }
807
808 /*
809 * https://github.com/symfony/symfony/issues/4242
810 */
811 public function testParseAfterError()
812 {
813 $this->testParseError('y-MMMMM-d', '1970-J-1');
814 $this->testParse('y-M-d', '1970-1-1', 0);
815 }
816
817 public function testParseWithNullPositionValue()
818 {
819 $position = null;
820 $formatter = $this->getDefaultDateFormatter('y');
821 $this->assertSame(0, $formatter->parse('1970', $position));
822 $this->assertNull($position);
823 }
824
825 public function testSetPattern()
826 {
827 $formatter = $this->getDefaultDateFormatter();
828 $formatter->setPattern('yyyy-MM-dd');
829 $this->assertEquals('yyyy-MM-dd', $formatter->getPattern());
830 }
831
832 /**
833 * @covers Symfony\Component\Intl\DateFormatter\IntlDateFormatter::getTimeZoneId
834 * @dataProvider setTimeZoneIdProvider
835 */
836 public function testSetTimeZoneId($timeZoneId, $expectedTimeZoneId)
837 {
838 $formatter = $this->getDefaultDateFormatter();
839
840 if (version_compare(PHP_VERSION, '5.5.0-dev', '>=')) {
841 $formatter->setTimeZone($timeZoneId);
842 } else {
843 $formatter->setTimeZoneId($timeZoneId);
844 }
845
846 $this->assertEquals($expectedTimeZoneId, $formatter->getTimeZoneId());
847 }
848
849 public function setTimeZoneIdProvider()
850 {
851 return array(
852 array('UTC', 'UTC'),
853 array('GMT', 'GMT'),
854 array('GMT-03:00', 'GMT-03:00'),
855 array('Europe/Zurich', 'Europe/Zurich'),
856 array('GMT-0300', 'GMT-0300'),
857 array('Foo/Bar', 'Foo/Bar'),
858 array('GMT+00:AA', 'GMT+00:AA'),
859 array('GMT+00AA', 'GMT+00AA'),
860 );
861 }
862
863 protected function getDefaultDateFormatter($pattern = null)
864 {
865 return $this->getDateFormatter('en', IntlDateFormatter::MEDIUM, IntlDateFormatter::SHORT, 'UTC', IntlDateFormatter::GREGORIAN, $pattern);
866 }
867
868 protected function getDateTime($timestamp = null)
869 {
870 if (version_compare(PHP_VERSION, '5.5.0-dev', '>=')) {
871 $timeZone = date_default_timezone_get();
872 } else {
873 $timeZone = getenv('TZ') ?: 'UTC';
874 }
875
876 $dateTime = new \DateTime();
877 $dateTime->setTimestamp(null === $timestamp ? time() : $timestamp);
878 $dateTime->setTimeZone(new \DateTimeZone($timeZone));
879
880 return $dateTime;
881 }
882
883 protected function assertIsIntlFailure($formatter, $errorMessage, $errorCode)
884 {
885 $this->assertSame($errorMessage, $this->getIntlErrorMessage());
886 $this->assertSame($errorCode, $this->getIntlErrorCode());
887 $this->assertTrue($this->isIntlFailure($this->getIntlErrorCode()));
888 $this->assertSame($errorMessage, $formatter->getErrorMessage());
889 $this->assertSame($errorCode, $formatter->getErrorCode());
890 $this->assertTrue($this->isIntlFailure($formatter->getErrorCode()));
891 }
892
893 protected function assertIsIntlSuccess($formatter, $errorMessage, $errorCode)
894 {
895 /* @var IntlDateFormatter $formatter */
896 $this->assertSame($errorMessage, $this->getIntlErrorMessage());
897 $this->assertSame($errorCode, $this->getIntlErrorCode());
898 $this->assertFalse($this->isIntlFailure($this->getIntlErrorCode()));
899 $this->assertSame($errorMessage, $formatter->getErrorMessage());
900 $this->assertSame($errorCode, $formatter->getErrorCode());
901 $this->assertFalse($this->isIntlFailure($formatter->getErrorCode()));
902 }
903
904 /**
905 * @param $locale
906 * @param $datetype
907 * @param $timetype
908 * @param null $timezone
909 * @param int $calendar
910 * @param null $pattern
911 *
912 * @return mixed
913 */
914 abstract protected function getDateFormatter($locale, $datetype, $timetype, $timezone = null, $calendar = IntlDateFormatter::GREGORIAN, $pattern = null);
915
916 /**
917 * @return string
918 */
919 abstract protected function getIntlErrorMessage();
920
921 /**
922 * @return integer
923 */
924 abstract protected function getIntlErrorCode();
925
926 /**
927 * @param integer $errorCode
928 *
929 * @return Boolean
930 */
931 abstract protected function isIntlFailure($errorCode);
932 }