diff --git a/core/modules/datetime/src/Plugin/Field/FieldFormatter/DateTimeDefaultFormatter.php b/core/modules/datetime/src/Plugin/Field/FieldFormatter/DateTimeDefaultFormatter.php index 03c92ae..b330179 100644 --- a/core/modules/datetime/src/Plugin/Field/FieldFormatter/DateTimeDefaultFormatter.php +++ b/core/modules/datetime/src/Plugin/Field/FieldFormatter/DateTimeDefaultFormatter.php @@ -50,7 +50,7 @@ public function viewElements(FieldItemListInterface $items, $langcode) { // Create the ISO date in Universal Time. $iso_date = $date->format("Y-m-d\TH:i:s") . 'Z'; - $this->setTimeZone($date); + $this->setTimeZone($date, $item->timezone); $output = $this->formatDate($date); } diff --git a/core/modules/datetime/src/Plugin/Field/FieldFormatter/DateTimeFormatterBase.php b/core/modules/datetime/src/Plugin/Field/FieldFormatter/DateTimeFormatterBase.php index 70b7ec1..9b8a670 100644 --- a/core/modules/datetime/src/Plugin/Field/FieldFormatter/DateTimeFormatterBase.php +++ b/core/modules/datetime/src/Plugin/Field/FieldFormatter/DateTimeFormatterBase.php @@ -83,6 +83,7 @@ public static function create(ContainerInterface $container, array $configuratio */ public static function defaultSettings() { return array( + 'timezone_display' => DateTimeItem::TIMEZONE_USER, 'timezone_override' => '', ) + parent::defaultSettings(); } @@ -93,16 +94,36 @@ public static function defaultSettings() { public function settingsForm(array $form, FormStateInterface $form_state) { $form = parent::settingsForm($form, $form_state); - // @todo There should be a way to specify/change which timezone the date - // is displayed with (eg, for an event site that spans multiple timezones, - // transforming the time into the site/user's timezone may not make sense). - $form['timezone_override'] = array( - '#type' => 'select', - '#title' => $this->t('Time zone override'), - '#description' => $this->t('The time zone selected here will always be used'), - '#options' => system_time_zones(TRUE), - '#default_value' => $this->getSetting('timezone_override'), - ); + // Timezone display is only applicable to datetime items. + if ($this->fieldDefinition->getFieldStorageDefinition()->getSetting('datetime_type') === DateTimeItem::DATETIME_TYPE_DATETIME) { + $form['timezone_display'] = array( + '#type' => 'select', + '#title' => $this->t('Timezone display'), + '#description' => $this->t('The timezone to use when displaying this date.'), + '#options' => array( + DateTimeItem::TIMEZONE_USER => $this->t("The user's timezone"), + DateTimeItem::TIMEZONE_NONE => $this->t("Timezone override") + ), + ); + + // If this field is using per-date timezone storage, add that as an option. + if ($this->fieldDefinition->getFieldStorageDefinition()->getSetting('timezone_handling') === DateTimeItem::TIMEZONE_DATE) { + $form['timezone_display']['#options'][DateTimeItem::TIMEZONE_DATE] = $this->t("The date's timezone"); + } + + $form['timezone_override'] = array( + '#type' => 'select', + '#title' => $this->t('Time zone override'), + '#description' => $this->t('The time zone selected here will always be used'), + '#options' => system_time_zones(TRUE), + '#default_value' => $this->getSetting('timezone_override'), + '#states' => array( + 'visible' => array( + ':input[name="fields[' . $this->fieldDefinition->getName() . '][settings_edit_form][settings][timezone_display]"]' => ['value' => DateTimeItem::TIMEZONE_NONE], + ), + ) + ); + } return $form; } @@ -113,8 +134,15 @@ public function settingsForm(array $form, FormStateInterface $form_state) { public function settingsSummary() { $summary = parent::settingsSummary(); - if ($override = $this->getSetting('timezone_override')) { - $summary[] = $this->t('Time zone: @timezone', array('@timezone' => $override)); + if ($this->fieldDefinition->getFieldStorageDefinition()->getSetting('datetime_type') === DateTimeItem::DATETIME_TYPE_DATETIME) { + if ($override = $this->getSetting('timezone_override')) { + $summary[] = $this->t('Time zone: @timezone', array('@timezone' => $override)); + } + else { + // @todo Make human-readable. + $summary[] = $this->t('Time zone display: @timezone', array('@timezone' => $this->getSetting('timezone_display'))); + + } } return $summary; @@ -142,13 +170,15 @@ public function settingsSummary() { * * @param \Drupal\Core\Datetime\DrupalDateTime $date * A DrupalDateTime object. + * @param string $timezone + * (optional) A timezone to explicitly set the date to. */ - protected function setTimeZone(DrupalDateTime $date) { + protected function setTimeZone(DrupalDateTime $date, $timezone = NULL) { if ($this->getFieldSetting('datetime_type') === DateTimeItem::DATETIME_TYPE_DATE) { // A date without time has no timezone conversion. $timezone = DATETIME_STORAGE_TIMEZONE; } - else { + elseif (empty($timezone)) { $timezone = drupal_get_user_timezone(); } $date->setTimeZone(timezone_open($timezone)); diff --git a/core/modules/datetime/src/Plugin/Field/FieldType/DateTimeItem.php b/core/modules/datetime/src/Plugin/Field/FieldType/DateTimeItem.php index 2f739d9..1727fd3 100644 --- a/core/modules/datetime/src/Plugin/Field/FieldType/DateTimeItem.php +++ b/core/modules/datetime/src/Plugin/Field/FieldType/DateTimeItem.php @@ -28,7 +28,7 @@ class DateTimeItem extends FieldItemBase { public static function defaultStorageSettings() { return array( 'datetime_type' => 'datetime', - 'timezone_handling' => 'site', + 'timezone_handling' => static::TIMEZONE_USER, ) + parent::defaultStorageSettings(); } @@ -43,6 +43,28 @@ public static function defaultStorageSettings() { const DATETIME_TYPE_DATETIME = 'datetime'; /** + * Timezone uses the site's timezone, regardless of the user's timezone. + */ + const TIMEZONE_SITE = 'site'; + + /** + * Timezone uses the user's timezone. + * + * @see drupal_get_user_timezone() + */ + const TIMEZONE_USER = 'user'; + + /** + * Timezone is set per-date. + */ + const TIMEZONE_DATE = 'date'; + + /** + * No timezone conversion is performed. + */ + const TIMEZONE_NONE = 'none'; + + /** * {@inheritdoc} */ public static function propertyDefinitions(FieldStorageDefinitionInterface $field_definition) { @@ -110,15 +132,15 @@ public function storageSettingsForm(array &$form, FormStateInterface $form_state '#type' => 'select', '#title' => t('Timezone handling'), '#options' => array( - 'site' => t("Site's timezone"), - 'date' => t("Date's timezone"), - 'user' => t("User's timezone"), - 'utc' => 'UTC', - 'none' => t('No timezone conversion'), + static::TIMEZONE_SITE => t("Site's timezone"), + static::TIMEZONE_DATE => t("Date's timezone"), + static::TIMEZONE_USER => t("User's timezone"), + static::TIMEZONE_NONE => t('No timezone conversion'), ), '#default_value' => $this->getSetting('timezone_handling'), '#required' => TRUE, '#states' => array( + // Hide the field if this is a date-only field. 'visible' => array( ':input[name="settings[datetime_type]"]' => ['value' => static::DATETIME_TYPE_DATETIME], ), diff --git a/core/modules/datetime/src/Plugin/Field/FieldWidget/DateTimeWidgetBase.php b/core/modules/datetime/src/Plugin/Field/FieldWidget/DateTimeWidgetBase.php index ef1661b..31e868e 100644 --- a/core/modules/datetime/src/Plugin/Field/FieldWidget/DateTimeWidgetBase.php +++ b/core/modules/datetime/src/Plugin/Field/FieldWidget/DateTimeWidgetBase.php @@ -40,12 +40,12 @@ public function formElement(FieldItemListInterface $items, $delta, array $elemen $element['value']['#date_timezone'] = DATETIME_STORAGE_TIMEZONE; } - if ($this->getFieldSetting('timezone_handling') === 'date') { + if ($this->getFieldSetting('timezone_handling') === DateTimeItem::TIMEZONE_DATE) { $element['timezone'] = array( '#type' => 'select', '#options' => array_combine(\DateTimeZone::listIdentifiers(), \DateTimeZone::listIdentifiers()), // Default to user's timezone. - '#default_value' => drupal_get_user_timezone(), + '#default_value' => $items[$delta]->timezone ?: drupal_get_user_timezone(), ); }