diff --git a/core/modules/datetime/src/Plugin/Field/FieldFormatter/DateRangeCustomFormatter.php b/core/modules/datetime/src/Plugin/Field/FieldFormatter/DateRangeCustomFormatter.php index 909f86f..c45c24d 100644 --- a/core/modules/datetime/src/Plugin/Field/FieldFormatter/DateRangeCustomFormatter.php +++ b/core/modules/datetime/src/Plugin/Field/FieldFormatter/DateRangeCustomFormatter.php @@ -80,7 +80,7 @@ public function viewElements(FieldItemListInterface $items, $langcode) { */ protected function formatDate($date) { $format = $this->getSetting('date_format'); - $timezone = $this->getSetting('timezone_override'); + $timezone = $this->getSetting('timezone_override') ?: $date->getTimezone()->getName(); return $this->dateFormatter->format($date->getTimestamp(), 'custom', $format, $timezone != '' ? $timezone : NULL); } diff --git a/core/modules/datetime/src/Plugin/Field/FieldFormatter/DateRangeDefaultFormatter.php b/core/modules/datetime/src/Plugin/Field/FieldFormatter/DateRangeDefaultFormatter.php index 785fa9a..1469bd4 100644 --- a/core/modules/datetime/src/Plugin/Field/FieldFormatter/DateRangeDefaultFormatter.php +++ b/core/modules/datetime/src/Plugin/Field/FieldFormatter/DateRangeDefaultFormatter.php @@ -115,7 +115,7 @@ public function viewElements(FieldItemListInterface $items, $langcode) { */ protected function formatDate($date) { $format_type = $this->getSetting('format_type'); - $timezone = $this->getSetting('timezone_override'); + $timezone = $this->getSetting('timezone_override') ?: $date->getTimezone()->getName(); return $this->dateFormatter->format($date->getTimestamp(), $format_type, '', $timezone != '' ? $timezone : NULL); } diff --git a/core/modules/datetime/src/Plugin/Field/FieldFormatter/DateRangeFormatterBase.php b/core/modules/datetime/src/Plugin/Field/FieldFormatter/DateRangeFormatterBase.php index befe395..f25ecf1 100644 --- a/core/modules/datetime/src/Plugin/Field/FieldFormatter/DateRangeFormatterBase.php +++ b/core/modules/datetime/src/Plugin/Field/FieldFormatter/DateRangeFormatterBase.php @@ -9,6 +9,7 @@ use Drupal\Core\Field\FormatterBase; use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Plugin\ContainerFactoryPluginInterface; +use Drupal\datetime\Plugin\Field\FieldType\DateRangeItem; use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\HttpFoundation\RequestStack; @@ -164,7 +165,14 @@ public function settingsSummary() { * A DrupalDateTime object. */ protected function setTimeZone(DrupalDateTime $date) { - $date->setTimeZone(timezone_open(drupal_get_user_timezone())); + if ($this->getFieldSetting('datetime_type') === DateRangeItem::DATERANGE_TYPE_DATE) { + // A date without time has no timezone conversion. + $timezone = DATETIME_STORAGE_TIMEZONE; + } + else { + $timezone = drupal_get_user_timezone(); + } + $date->setTimeZone(timezone_open($timezone)); } /** diff --git a/core/modules/datetime/src/Plugin/Field/FieldFormatter/DateRangePlainFormatter.php b/core/modules/datetime/src/Plugin/Field/FieldFormatter/DateRangePlainFormatter.php index 7b77a06..a2a1b13 100644 --- a/core/modules/datetime/src/Plugin/Field/FieldFormatter/DateRangePlainFormatter.php +++ b/core/modules/datetime/src/Plugin/Field/FieldFormatter/DateRangePlainFormatter.php @@ -69,7 +69,7 @@ public function viewElements(FieldItemListInterface $items, $langcode) { */ protected function formatDate($date) { $format = $this->getFieldSetting('daterange_type') == DateRangeItem::DATERANGE_TYPE_DATE ? DATETIME_DATE_STORAGE_FORMAT : DATETIME_DATETIME_STORAGE_FORMAT; - $timezone = $this->getSetting('timezone_override'); + $timezone = $this->getSetting('timezone_override') ?: $date->getTimezone()->getName(); return $this->dateFormatter->format($date->getTimestamp(), 'custom', $format, $timezone != '' ? $timezone : NULL); } diff --git a/core/modules/datetime/src/Plugin/Field/FieldWidget/DateRangeWidgetBase.php b/core/modules/datetime/src/Plugin/Field/FieldWidget/DateRangeWidgetBase.php index 08d635e..49c5564 100644 --- a/core/modules/datetime/src/Plugin/Field/FieldWidget/DateRangeWidgetBase.php +++ b/core/modules/datetime/src/Plugin/Field/FieldWidget/DateRangeWidgetBase.php @@ -45,6 +45,13 @@ public function formElement(FieldItemListInterface $items, $delta, array $elemen '#required' => $element['#required'], ); + if ($this->getFieldSetting('datetime_type') == DateRangeItem::DATERANGE_TYPE_DATE) { + // A date-only field should have no timezone conversion performed, so + // use the same timezone as for storage. + $element['value']['#date_timezone'] = DATETIME_STORAGE_TIMEZONE; + $element['value2']['#date_timezone'] = DATETIME_STORAGE_TIMEZONE; + } + if ($items[$delta]->start_date) { /** @var \Drupal\Core\Datetime\DrupalDateTime $start_date */ $start_date = $items[$delta]->start_date; diff --git a/core/modules/datetime/src/Tests/DateRangeFieldTest.php b/core/modules/datetime/src/Tests/DateRangeFieldTest.php index 556a6fa..7d1e97b 100644 --- a/core/modules/datetime/src/Tests/DateRangeFieldTest.php +++ b/core/modules/datetime/src/Tests/DateRangeFieldTest.php @@ -55,6 +55,28 @@ class DateRangeFieldTest extends WebTestBase { protected $field; /** + + * An array of timezone extremes to test. + + * + + * @var string[] + + */ + protected static $timezones = [ + // UTC-12, no DST. + 'Pacific/Kwajalein', + // UTC-11, no DST + 'Pacific/Midway', + // UTC-7, no DST. + 'America/Phoenix', + // UTC. + 'UTC', + // UTC+5:30, no DST. + 'Asia/Kolkata', + // UTC+12, no DST + 'Pacific/Funafuti', + // UTC+13, no DST. + 'Pacific/Tongatapu', + ]; + + /** * {@inheritdoc} */ protected function setUp() { @@ -1152,4 +1174,19 @@ protected function renderTestEntity($id, $view_mode = 'full', $reset = TRUE) { $this->verbose($output); } + /** + * Sets the site timezone to a given timezone. + * + * @param string $timezone + * The timezone identifier to set. + */ + protected function setSiteTimezone($timezone) { + // Set an explicit site timezone, and disallow per-user timezones. + $this->config('system.date') + ->set('timezone.user.configurable', 0) + // A timezone with an offset greater than UTC+12 is used. + ->set('timezone.default', $timezone) + ->save(); + } + }