diff --git a/core/lib/Drupal/Component/Datetime/DateTimePlus.php b/core/lib/Drupal/Component/Datetime/DateTimePlus.php index 283daae..b00124b 100644 --- a/core/lib/Drupal/Component/Datetime/DateTimePlus.php +++ b/core/lib/Drupal/Component/Datetime/DateTimePlus.php @@ -637,9 +637,25 @@ public static function datePad($value, $size = 2) { /** * Tests whether the IntlDateFormatter can be used. + * + * @param string $calendar + * (optional) String calendar name to use for the date. Defaults to NULL. + * @param string $langcode + * (optional) String two letter language code to construct the locale string + * by the intlDateFormatter class. Defaults to NULL. + * @param string $country + * (optional) String two letter country code to construct the locale string + * by the intlDateFormatter class. Defaults to NULL. + * + * @return bool + * TRUE if IntlDateFormatter can be used. */ - public function canUseIntl() { - return class_exists('IntlDateFormatter') && !empty($this->calendar) && !empty($this->langcode) && !empty($this->country); + public function canUseIntl($calendar = NULL, $langcode = NULL, $country = NULL) { + $langcode = !empty($langcode) ? $langcode : $this->langcode; + $country = !empty($country) ? $country : $this->country; + $calendar = !empty($calendar) ? $calendar : $this->calendar; + + return class_exists('IntlDateFormatter') && !empty($calendar) && !empty($langcode) && !empty($country); } /** @@ -691,14 +707,12 @@ public function format($format, $settings = array()) { $langcode = !empty($settings['langcode']) ? $settings['langcode'] : $this->langcode; $country = !empty($settings['country']) ? $settings['country'] : $this->country; $calendar = !empty($settings['calendar']) ? $settings['calendar'] : $this->calendar; - $timezone = !empty($settings['timezone']) ? $settings['timezone'] : $this->getTimezone()->getName(); - $lenient = !empty($settings['lenient']) ? $settings['lenient'] : FALSE; // Format the date and catch errors. try { // If we have what we need to use the IntlDateFormatter, do so. - if ($this->canUseIntl() && $format_string_type == static::INTL) { + if ($this->canUseIntl($calendar, $langcode, $country) && $format_string_type == static::INTL) { // Construct the $locale variable needed by the IntlDateFormatter. $locale = $langcode . '_' . $country; @@ -716,9 +730,12 @@ public function format($format, $settings = array()) { $date_type = !empty($settings['date_type']) ? $settings['date_type'] : \IntlDateFormatter::FULL; $time_type = !empty($settings['time_type']) ? $settings['time_type'] : \IntlDateFormatter::FULL; - $formatter = new \IntlDateFormatter($locale, $date_type, $time_type, $timezone, $calendar_type); + $timezone = !empty($settings['timezone']) ? $settings['timezone'] : $this->getTimezone()->getName(); + $formatter = new \IntlDateFormatter($locale, $date_type, $time_type, $timezone, $calendar_type, $format); + + $lenient = !empty($settings['lenient']) ? $settings['lenient'] : FALSE; $formatter->setLenient($lenient); - $value = $formatter->format($format); + $value = $formatter->format($this); } // Otherwise, use the parent method. diff --git a/core/lib/Drupal/Core/Datetime/DrupalDateTime.php b/core/lib/Drupal/Core/Datetime/DrupalDateTime.php index 6d60656..468c583 100644 --- a/core/lib/Drupal/Core/Datetime/DrupalDateTime.php +++ b/core/lib/Drupal/Core/Datetime/DrupalDateTime.php @@ -123,6 +123,7 @@ public function format($format, $settings = array()) { $format_string_type = isset($settings['format_string_type']) ? $settings['format_string_type'] : static::PHP; + $settings['calendar'] = !empty($settings['calendar']) ? $settings['calendar'] : $this->calendar; $settings['langcode'] = !empty($settings['langcode']) ? $settings['langcode'] : $this->langcode; $settings['country'] = !empty($settings['country']) ? $settings['country'] : $this->country; @@ -130,7 +131,7 @@ public function format($format, $settings = array()) { try { // If we have what we need to use the IntlDateFormatter, do so. - if ($this->canUseIntl() && $format_string_type == parent::INTL) { + if ($this->canUseIntl($settings['calendar'], $settings['langcode'], $settings['country']) && $format_string_type == parent::INTL) { $value = parent::format($format, $settings); } diff --git a/core/modules/system/config/system.date.yml b/core/modules/system/config/system.date.yml index 82a22bc..55c6e75 100644 --- a/core/modules/system/config/system.date.yml +++ b/core/modules/system/config/system.date.yml @@ -24,7 +24,7 @@ formats: name: 'HTML Datetime' pattern: php: 'Y-m-d\TH:i:sO' - intl: "yyyy-MM-dd'Tkk:mm:ssZZ" + intl: 'yyyy-MM-dd''T''kk:mm:ssZZ' locked: 1 html_date: name: 'HTML Date' @@ -48,7 +48,7 @@ formats: name: 'HTML Week' pattern: php: 'Y-\WW' - intl: "Y-'WW" + intl: 'Y-''W''WW' locked: 1 html_month: name: 'HTML Month' diff --git a/core/modules/system/lib/Drupal/system/Tests/Datetime/DateTimePlusIntlTest.php b/core/modules/system/lib/Drupal/system/Tests/Datetime/DateTimePlusIntlTest.php new file mode 100644 index 0000000..02ec6ec --- /dev/null +++ b/core/modules/system/lib/Drupal/system/Tests/Datetime/DateTimePlusIntlTest.php @@ -0,0 +1,88 @@ + 'DateTimePlusIntl', + 'description' => 'Test DateTimePlus PECL Intl functionality.', + 'group' => 'Datetime', + ); + } + + protected function setUp() { + parent::setUp(); + // Install default config for system. + $this->installConfig(array('system')); + } + + /** + * Ensures that the PHP's Intl extension is installed. + * + * @return array + * Array of errors containing a list of unmet requirements. + */ + function checkRequirements() { + if (!class_exists('IntlDateFormatter')) { + return array( + 'PHP\'s Intl extension needs to be installed and enabled.', + ); + } + return parent::checkRequirements(); + } + + /** + * Tests that PHP and Intl default formats are equivalent. + */ + function testDateTimestampIntl() { + + // Create date object from a unix timestamp and display it in + // local time. + $input = '2007-01-31 21:00:00'; + $timezone = 'UTC'; + $intl_settings = array( + 'format_string_type' => DateTimePlus::INTL, + 'country' => 'US', + 'langcode' => 'en', + ); + $php_settings = array( + 'country' => NULL, + 'langcode' => 'en', + ); + + $intl_date = new DateTimePlus($input, $timezone, NULL, $intl_settings); + $php_date = new DateTimePlus($input, $timezone, NULL, $php_settings); + + $this->assertTrue($intl_date->canUseIntl(), 'DateTimePlus object can use intl when provided with country and langcode settings.'); + $this->assertFalse($php_date->canUseIntl(), 'DateTimePlus object will fallback to use PHP when not provided with country setting.'); + + $default_formats = config('system.date')->get('formats'); + + foreach ($default_formats as $format) { + $php_format = $php_date->format($format['pattern']['php'], $php_settings); + $intl_format = $intl_date->format($format['pattern']['intl'], $intl_settings); + $this->assertIdentical($intl_format, $php_format); + } + } + +}