diff --git a/core/lib/Drupal/Component/Datetime/DateTimePlus.php b/core/lib/Drupal/Component/Datetime/DateTimePlus.php index cda7f3e..1b1026f 100644 --- a/core/lib/Drupal/Component/Datetime/DateTimePlus.php +++ b/core/lib/Drupal/Component/Datetime/DateTimePlus.php @@ -204,12 +204,49 @@ public static function createFromFormat($format, $time, $timezone = NULL, $setti // A regular try/catch won't work right here, if the value is // invalid it doesn't return an exception. $datetimeplus = new static('', $timezone, $settings); + + $format_string_type = isset($settings['format_string_type']) ? $settings['format_string_type'] : static::PHP; + if ($datetimeplus->canUseIntl() && $format_string_type == static::INTL) { + // Construct the $locale variable needed by the IntlDateFormatter. + $locale = $datetimeplus->langcode . '_' . $datetimeplus->country; + + // If we have information about a calendar, add it. + if (!empty($datetimeplus->calendar) && $datetimeplus->calendar != static::CALENDAR) { + $locale .= '@calendar=' . $datetimeplus->calendar; + } - $date = \DateTime::createFromFormat($format, $time, $datetimeplus->getTimezone()); + // If we're working with a non-gregorian calendar, indicate that. + $calendar_type = \IntlDateFormatter::GREGORIAN; + if ($datetimeplus->calendar != self::CALENDAR) { + $calendar_type = \IntlDateFormatter::TRADITIONAL; + } + + $date_type = !empty($settings['date_type']) ? $settings['date_type'] : \IntlDateFormatter::FULL; + $time_type = !empty($settings['time_type']) ? $settings['time_type'] : \IntlDateFormatter::FULL; + $timezone = !empty($settings['timezone']) ? $settings['timezone'] : $datetimeplus->getTimezone()->getName(); + $formatter = new \IntlDateFormatter($locale, $date_type, $time_type, $timezone, $calendar_type, $format); + + $timestamp = $formatter->parse($time); + if ($timestamp) { + $date = $datetimeplus->createFromTimestamp($timestamp, $timezone, $settings); + } + else { + $date = NULL; + } + } + else { + $date = \DateTime::createFromFormat($format, $time, $datetimeplus->getTimezone()); + } if (!$date instanceOf \DateTime) { throw new \Exception('The date cannot be created from a format.'); } else { + if ($date instanceOf DateTimePlus) { + $test_time = $date->format($format, $settings); + } + elseif ($date instanceOf \DateTime) { + $test_time = $date->format($format); + } $datetimeplus->setTimestamp($date->getTimestamp()); $datetimeplus->setTimezone($date->getTimezone()); @@ -218,7 +255,7 @@ public static function createFromFormat($format, $time, $timezone = NULL, $setti // instance, an input value of '11' using a format of Y (4 digits) gets // created as '0011' instead of '2011'. Use the parent::format() because // we do not want to use the IntlDateFormatter here. - if ($settings['validate_format'] && $date->format($format) != $time) { + if ($settings['validate_format'] && $test_time != $time) { throw new \Exception('The created date does not match the input value.'); } } diff --git a/core/lib/Drupal/Core/Datetime/DrupalDateTime.php b/core/lib/Drupal/Core/Datetime/DrupalDateTime.php index de6c0f8..ffd9b99 100644 --- a/core/lib/Drupal/Core/Datetime/DrupalDateTime.php +++ b/core/lib/Drupal/Core/Datetime/DrupalDateTime.php @@ -124,7 +124,7 @@ public function format($format, $settings = array()) { $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; - + $settings['format_string_type'] = $format_string_type; // Format the date and catch errors. try { @@ -142,7 +142,7 @@ public function format($format, $settings = array()) { // Paired backslashes are isolated to prevent errors in // read-ahead evaluation. The read-ahead expression ensures that // A matches, but not \A. - $format = preg_replace(array('/\\\\\\\\/', '/(? 'datetime_form', '#theme_wrappers' => array('datetime_wrapper'), '#date_date_format' => $date_format, + '#date_format_string_type' => $format_type, '#date_date_element' => 'date', '#date_date_callbacks' => array(), '#date_time_format' => $time_format, @@ -383,7 +384,7 @@ function template_preprocess_datetime_wrapper(&$variables) { * The form element whose value has been processed. */ function datetime_datetime_form_process($element, &$form_state) { - + $format_settings = array('format_string_type' => $element['#date_format_string_type']); // The value callback has populated the #value array. $date = !empty($element['#value']['object']) ? $element['#value']['object'] : NULL; @@ -403,7 +404,7 @@ function datetime_datetime_form_process($element, &$form_state) { if ($element['#date_date_element'] != 'none') { $date_format = $element['#date_date_element'] != 'none' ? datetime_html5_format('date', $element) : ''; - $date_value = !empty($date) ? $date->format($date_format) : $element['#value']['date']; + $date_value = !empty($date) ? $date->format($date_format, $format_settings) : $element['#value']['date']; // Creating format examples on every individual date item is messy, and // placeholders are invalid for HTML5 date and datetime, so an example @@ -422,8 +423,8 @@ function datetime_datetime_form_process($element, &$form_state) { $html5_max->setDate($range[1], 12, 31)->setTime(23, 59, 59); $extra_attributes += array( - 'min' => $html5_min->format($date_format), - 'max' => $html5_max->format($date_format), + 'min' => $html5_min->format($date_format, $format_settings), + 'max' => $html5_max->format($date_format, $format_settings), ); } @@ -450,7 +451,7 @@ function datetime_datetime_form_process($element, &$form_state) { if ($element['#date_time_element'] != 'none') { $time_format = $element['#date_time_element'] != 'none' ? datetime_html5_format('time', $element) : ''; - $time_value = !empty($date) ? $date->format($time_format) : $element['#value']['time']; + $time_value = !empty($date) ? $date->format($time_format, $format_settings) : $element['#value']['time']; // Adds the HTML5 attributes. $extra_attributes = array( @@ -508,7 +509,7 @@ function form_type_datetime_value($element, $input = FALSE) { } try { - $date = DrupalDateTime::createFromFormat(trim($date_format . ' ' . $time_format), trim($date_input . ' ' . $time_input), $timezone); + $date = DrupalDateTime::createFromFormat(trim($date_format . ' ' . $time_format), trim($date_input . ' ' . $time_input), $timezone, array('format_string_type' => $element['#date_format_string_type'])); } catch (\Exception $e) { $date = NULL; @@ -523,8 +524,8 @@ function form_type_datetime_value($element, $input = FALSE) { $date = $element['#default_value']; if ($date instanceOf DrupalDateTime && !$date->hasErrors()) { $input = array( - 'date' => $date->format($element['#date_date_format']), - 'time' => $date->format($element['#date_time_format']), + 'date' => $date->format($element['#date_date_format'], array('format_string_type' => $element['#date_format_string_type'])), + 'time' => $date->format($element['#date_time_format'], array('format_string_type' => $element['#date_format_string_type'])), 'object' => $date, ); } @@ -643,11 +644,12 @@ function datetime_html5_format($part, $element) { * */ function datetime_format_example($format) { + $format_type = datetime_default_format_type(); $date = &drupal_static(__FUNCTION__); if (empty($date)) { $date = new DrupalDateTime(); } - return $date->format($format); + return $date->format($format, array('format_string_type' => $format_type)); } /**