diff --git a/src/Symfony/Component/Locale/Stub/DateFormat/AmPmTransformer.php b/src/Symfony/Component/Locale/Stub/DateFormat/AmPmTransformer.php index d6be49a32b..6bd3a5c08c 100644 --- a/src/Symfony/Component/Locale/Stub/DateFormat/AmPmTransformer.php +++ b/src/Symfony/Component/Locale/Stub/DateFormat/AmPmTransformer.php @@ -25,11 +25,13 @@ class AmPmTransformer extends Transformer public function getReverseMatchingRegExp($length) { - return "AM|PM"; + return "?PAM|PM"; } public function extractDateOptions($matched, $length) { - return array(); + return array( + 'marker' => $matched + ); } } diff --git a/src/Symfony/Component/Locale/Stub/DateFormat/FullTransformer.php b/src/Symfony/Component/Locale/Stub/DateFormat/FullTransformer.php index b503984fd1..dbfb5df209 100644 --- a/src/Symfony/Component/Locale/Stub/DateFormat/FullTransformer.php +++ b/src/Symfony/Component/Locale/Stub/DateFormat/FullTransformer.php @@ -173,18 +173,45 @@ class FullTransformer { $datetime = $this->extractDateTime($options); - $year = $datetime['year']; - $month = $datetime['month']; - $day = $datetime['day']; - $hour = $datetime['hour']; - $minute = $datetime['minute']; - $second = $datetime['second']; + $year = $datetime['year']; + $month = $datetime['month']; + $day = $datetime['day']; + $hour = $datetime['hour']; + $minute = $datetime['minute']; + $second = $datetime['second']; + $marker = $datetime['marker']; + $hourType = $datetime['hourType']; // If month is false, return immediately if (false === $month) { return false; } + // If the AM/PM marker is AM or null, the hour is 12 (1-12) and the capture was 'h' or 'hh', the hour is 0 + if ('1201' === $hourType && 'PM' !== $marker && 12 === $hour) { + $hour = 0; + } + + // If PM and hour is not 12 (1-12), sum 12 hour + if ('1201' === $hourType && 'PM' === $marker && 12 !== $hour) { + $hour = $hour + 12; + } + + // If PM, sum 12 hours when 12 hour (0-11) + if ('1200' === $hourType && 'PM' === $marker) { + $hour = $hour + 12; + } + + // If 24 hours (0-23 or 1-24) and marker is set, hour is 0 + if (('2400' === $hourType || '2401' === $hourType) && null !== $marker) { + $hour = 0; + } + + // If 24 hours (1-24) and hour is 24, hour is 0 + if ('2401' === $hourType && 24 === $hour) { + $hour = 0; + } + // Set the timezone $originalTimezone = date_default_timezone_get(); date_default_timezone_set($this->timezone); @@ -200,12 +227,14 @@ class FullTransformer private function extractDateTime(array $datetime) { return array( - 'year' => isset($datetime['year']) ? $datetime['year'] : 1970, - 'month' => isset($datetime['month']) ? $datetime['month'] : 1, - 'day' => isset($datetime['day']) ? $datetime['day'] : 1, - 'hour' => isset($datetime['hour']) ? $datetime['hour'] : 0, - 'minute' => isset($datetime['minute']) ? $datetime['minute'] : 0, - 'second' => isset($datetime['second']) ? $datetime['second'] : 0, + 'year' => isset($datetime['year']) ? $datetime['year'] : 1970, + 'month' => isset($datetime['month']) ? $datetime['month'] : 1, + 'day' => isset($datetime['day']) ? $datetime['day'] : 1, + 'hour' => isset($datetime['hour']) ? $datetime['hour'] : 0, + 'minute' => isset($datetime['minute']) ? $datetime['minute'] : 0, + 'second' => isset($datetime['second']) ? $datetime['second'] : 0, + 'marker' => isset($datetime['marker']) ? $datetime['marker'] : null, + 'hourType' => isset($datetime['hourType']) ? $datetime['hourType'] : null, ); } } diff --git a/src/Symfony/Component/Locale/Stub/DateFormat/Hour1200Transformer.php b/src/Symfony/Component/Locale/Stub/DateFormat/Hour1200Transformer.php index 988ad89e27..a5b5bd8096 100644 --- a/src/Symfony/Component/Locale/Stub/DateFormat/Hour1200Transformer.php +++ b/src/Symfony/Component/Locale/Stub/DateFormat/Hour1200Transformer.php @@ -27,13 +27,15 @@ class Hour1200Transformer extends Transformer public function getReverseMatchingRegExp($length) { - return "\d{1,$length}"; + $capture = str_pad('', $length, 'K'); + return '?P<'.$capture.'>\d{1,2}'; } public function extractDateOptions($matched, $length) { return array( 'hour' => (int) $matched, + 'hourType' => '1200' ); } } diff --git a/src/Symfony/Component/Locale/Stub/DateFormat/Hour1201Transformer.php b/src/Symfony/Component/Locale/Stub/DateFormat/Hour1201Transformer.php index 974c1898c3..9ddd78c02e 100644 --- a/src/Symfony/Component/Locale/Stub/DateFormat/Hour1201Transformer.php +++ b/src/Symfony/Component/Locale/Stub/DateFormat/Hour1201Transformer.php @@ -25,13 +25,15 @@ class Hour1201Transformer extends Transformer public function getReverseMatchingRegExp($length) { - return "\d{1,$length}"; + $capture = str_pad('', $length, 'h'); + return '?P<'.$capture.'>\d{1,2}'; } public function extractDateOptions($matched, $length) { return array( 'hour' => (int) $matched, + 'hourType' => '1201' ); } } diff --git a/src/Symfony/Component/Locale/Stub/DateFormat/Hour2400Transformer.php b/src/Symfony/Component/Locale/Stub/DateFormat/Hour2400Transformer.php index ce59cebb95..0a7d56b004 100644 --- a/src/Symfony/Component/Locale/Stub/DateFormat/Hour2400Transformer.php +++ b/src/Symfony/Component/Locale/Stub/DateFormat/Hour2400Transformer.php @@ -25,13 +25,15 @@ class Hour2400Transformer extends Transformer public function getReverseMatchingRegExp($length) { - return "\d{1,$length}"; + $capture = str_pad('', $length, 'H'); + return '?P<'.$capture.'>\d{1,2}'; } public function extractDateOptions($matched, $length) { return array( 'hour' => (int) $matched, + 'hourType' => '2400' ); } } diff --git a/src/Symfony/Component/Locale/Stub/DateFormat/Hour2401Transformer.php b/src/Symfony/Component/Locale/Stub/DateFormat/Hour2401Transformer.php index f707f0b02b..2c1735cc81 100644 --- a/src/Symfony/Component/Locale/Stub/DateFormat/Hour2401Transformer.php +++ b/src/Symfony/Component/Locale/Stub/DateFormat/Hour2401Transformer.php @@ -27,13 +27,15 @@ class Hour2401Transformer extends Transformer public function getReverseMatchingRegExp($length) { - return "\d{1,$length}"; + $capture = str_pad('', $length, 'k'); + return '?P<'.$capture.'>\d{1,2}'; } public function extractDateOptions($matched, $length) { return array( 'hour' => (int) $matched, + 'hourType' => '2401' ); } } diff --git a/tests/Symfony/Tests/Component/Locale/Stub/StubIntlDateFormatterTest.php b/tests/Symfony/Tests/Component/Locale/Stub/StubIntlDateFormatterTest.php index 783da8597d..96ff14357b 100644 --- a/tests/Symfony/Tests/Component/Locale/Stub/StubIntlDateFormatterTest.php +++ b/tests/Symfony/Tests/Component/Locale/Stub/StubIntlDateFormatterTest.php @@ -470,6 +470,48 @@ class StubIntlDateFormatterTest extends LocaleTestCase array('y-M-d', '1970-1-1', 0), array('y-M-dd', '1970-1-01', 0), array('y-M-ddd', '1970-1-001', 0), + + // 12 hours (1-12) + array('y-M-d h', '1970-1-1 1', 3600), + array('y-M-d h', '1970-1-1 10', 36000), + array('y-M-d hh', '1970-1-1 11', 39600), + array('y-M-d hh', '1970-1-1 12', 0), + array('y-M-d hh a', '1970-1-1 12 AM', 0), + array('y-M-d hh a', '1970-1-1 12 PM', 43200), + array('y-M-d hh a', '1970-1-1 11 AM', 39600), + array('y-M-d hh a', '1970-1-1 11 PM', 82800), + + // 12 hours (0-11) + array('y-M-d K', '1970-1-1 1', 3600), + array('y-M-d K', '1970-1-1 10', 36000), + array('y-M-d KK', '1970-1-1 11', 39600), + array('y-M-d KK', '1970-1-1 12', 43200), + array('y-M-d KK a', '1970-1-1 12 AM', 43200), + array('y-M-d KK a', '1970-1-1 12 PM', 86400), + array('y-M-d KK a', '1970-1-1 10 AM', 36000), + array('y-M-d KK a', '1970-1-1 10 PM', 79200), + + // 24 hours (0-23) + array('y-M-d H', '1970-1-1 0', 0), + array('y-M-d H', '1970-1-1 1', 3600), + array('y-M-d H', '1970-1-1 10', 36000), + array('y-M-d HH', '1970-1-1 11', 39600), + array('y-M-d HH', '1970-1-1 12', 43200), + array('y-M-d HH', '1970-1-1 23', 82800), + array('y-M-d HH a', '1970-1-1 11 AM', 0), + array('y-M-d HH a', '1970-1-1 12 AM', 0), + array('y-M-d HH a', '1970-1-1 23 AM', 0), + + // 24 hours (1-24) + array('y-M-d k', '1970-1-1 1', 3600), + array('y-M-d k', '1970-1-1 10', 36000), + array('y-M-d kk', '1970-1-1 11', 39600), + array('y-M-d kk', '1970-1-1 12', 43200), + array('y-M-d kk', '1970-1-1 23', 82800), + array('y-M-d kk', '1970-1-1 24', 0), + array('y-M-d kk a', '1970-1-1 11 AM', 0), + array('y-M-d kk a', '1970-1-1 12 AM', 0), + array('y-M-d kk a', '1970-1-1 23 AM', 0), ); }