Loading config/schema/datetime_timezone.schema.yml +12 −0 Original line number Diff line number Diff line field.storage_settings.datetime_timezone: type: field.storage_settings.datetime label: 'Datetime Timezone field' field.value.datetime_timezone: type: field.value.datetime label: 'Default value' field.formatter.settings.datetime_timezone_default: type: mapping label: 'Date and timezone formatter' mapping: format_type: type: string label: 'The date format' src/Plugin/Field/FieldFormatter/DateTimeTimezoneDefaultFormatter.php 0 → 100755 +49 −0 Original line number Diff line number Diff line <?php namespace Drupal\datetime_timezone\Plugin\Field\FieldFormatter; use Drupal\Core\Field\FieldItemListInterface; /** * Plugin implementation of the 'Default' formatter for 'datetime_timezone'. * * @FieldFormatter( * id = "datetime_timezone_default", * label = @Translation("Default"), * field_types = { * "datetime_timezone" * } * ) */ class DateTimeTimezoneDefaultFormatter extends DateTimeTimezoneFormatterBase { /** * {@inheritdoc} */ public function viewElements(FieldItemListInterface $items, $langcode) { $build = []; foreach ($items as $delta => $item) { if ($item->value) { // Create the ISO date in Universal Time. $date = $item->date; $iso_date = $date->format('Y-m-d\TH:i:s', ['timezone' => $item->timezone]) . 'Z'; $build[$delta] = [ '#theme' => 'time', '#text' => $this->formatDate($date, $item->timezone), '#attributes' => [ 'datetime' => $iso_date, ], '#cache' => [ 'contexts' => [ 'timezone', ], ], ]; } } return $build; } } src/Plugin/Field/FieldFormatter/DateTimeTimezoneFormatterBase.php 0 → 100755 +120 −0 Original line number Diff line number Diff line <?php namespace Drupal\datetime_timezone\Plugin\Field\FieldFormatter; use Drupal\Core\Datetime\DrupalDateTime; use Drupal\Core\Field\FormatterBase; use Drupal\Core\Form\FormStateInterface; use Symfony\Component\DependencyInjection\ContainerInterface; abstract class DateTimeTimezoneFormatterBase extends FormatterBase { /** * The date formatter service. * * @var \Drupal\Core\Datetime\DateFormatterInterface */ protected $dateFormatter; /** * The date format entity storage. * * @var \Drupal\Core\Entity\EntityStorageInterface */ protected $dateFormatStorage; /** * {@inheritdoc} */ public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) { $instance = new static( $plugin_id, $plugin_definition, $configuration['field_definition'], $configuration['settings'], $configuration['label'], $configuration['view_mode'], $configuration['third_party_settings'] ); $instance->dateFormatter = $container->get('date.formatter'); $instance->dateFormatStorage = $container->get('entity_type.manager')->getStorage('date_format'); return $instance; } /** * {@inheritdoc} */ public static function defaultSettings() { return [ 'format_type' => 'medium', ] + parent::defaultSettings(); } /** * {@inheritdoc} */ public function settingsForm(array $form, FormStateInterface $form_state) { $form = parent::settingsForm($form, $form_state); $form['format_type'] = [ '#type' => 'select', '#title' => $this->t('Date format'), '#description' => $this->t('Choose a format for displaying the date. Be sure to set a format appropriate for the field, i.e. omitting time for a field that only has a date.'), '#options' => $this->getDateFormatOptions(), '#default_value' => $this->getSetting('format_type'), ]; return $form; } /** * {@inheritdoc} */ public function settingsSummary() { $summary = parent::settingsSummary(); $date = new DrupalDateTime(); $summary[] = $this->t('Format: @display', ['@display' => $this->formatDate($date)]); return $summary; } /** * Formats the date with the selected type. * * @param \Drupal\Core\Datetime\DrupalDateTime $date * The date object. * @param string|null $timezone * The timezone if we want to take it into account when rendering. * * @return string * The formatted date. */ protected function formatDate(DrupalDateTime $date, string $timezone = NULL): string { $format_type = $this->getSetting('format_type'); return $this->dateFormatter->format($date->getTimestamp(), $format_type, '', $timezone); } /** * Gets the date format options. * * @return array * An array of options to be used in the form. * * @see \Drupal\datetime\Plugin\Field\FieldFormatter\DateTimeDefaultFormatter */ protected function getDateFormatOptions() { $time = new DrupalDateTime(); $format_types = $this->dateFormatStorage->loadMultiple(); $options = []; foreach ($format_types as $type => $type_info) { $format = $this->dateFormatter->format($time->getTimestamp(), $type); $options[$type] = sprintf('%s (%s)', $type_info->label(), $format); } return $options; } } src/Plugin/Field/FieldType/DateTimeTimezoneItem.php +1 −1 Original line number Diff line number Diff line Loading @@ -16,7 +16,7 @@ use Drupal\datetime\Plugin\Field\FieldType\DateTimeItem; * label = @Translation("Date with timezone"), * description = @Translation("Create and store date with timezone information."), * default_widget = "datetime_timezone", * default_formatter = "datetime_default", * default_formatter = "datetime_timezone_default", * list_class = "\Drupal\datetime\Plugin\Field\FieldType\DateTimeFieldItemList" * ) */ Loading tests/src/Kernel/DateTimeTimezoneFormatterTest.php 0 → 100755 +95 −0 Original line number Diff line number Diff line <?php namespace Drupal\Tests\datetime_timezone\Kernel; use Drupal\Core\Datetime\DrupalDateTime; use Drupal\Core\Entity\Entity\EntityViewDisplay; use Drupal\datetime\Plugin\Field\FieldType\DateTimeItemInterface; use Drupal\entity_test\Entity\EntityTest; use Drupal\field\Entity\FieldConfig; use Drupal\field\Entity\FieldStorageConfig; use Drupal\KernelTests\KernelTestBase; /** * Test the default formatter. * * @group datetime_timezone */ class DateTimeTimezoneFormatterTest extends KernelTestBase { /** * Modules to enable. * * @var array */ public static $modules = [ 'user', 'system', 'field', 'text', 'entity_test', 'datetime', 'datetime_timezone', ]; /** * {@inheritdoc} */ protected function setUp() { parent::setUp(); $this->installConfig(['system']); $this->installEntitySchema('entity_test'); EntityViewDisplay::create([ 'targetEntityType' => 'entity_test', 'bundle' => 'entity_test', 'mode' => 'default', ])->save(); $field_storage = FieldStorageConfig::create([ 'field_name' => 'date', 'entity_type' => 'entity_test', 'type' => 'datetime_timezone', ]); $field_storage->save(); $field_config = FieldConfig::create([ 'field_storage' => $field_storage, 'bundle' => 'entity_test', ]); $field_config->save(); /* @var $entity_display_repository \Drupal\Core\Entity\EntityDisplayRepositoryInterface */ $entity_display_repository = \Drupal::service('entity_display.repository'); $entity_display_repository->getViewDisplay('entity_test', 'entity_test', 'default') ->setComponent('date', [ 'type' => 'datetime_timezone_default', ]) ->save(); } /** * Ensure the field is rendered in the correct timezone. */ public function testRenderedInCorrectTimezone() { $timezone = 'America/New_York'; $date = new DrupalDateTime('2017-03-25 10:30:00', 'UTC'); $entity = EntityTest::create([ 'date' => [ 'value' => $date->format(DateTimeItemInterface::DATETIME_STORAGE_FORMAT), 'timezone' => $timezone, ], ]); $entity->save(); // Render the field. $output = $entity->date->view([]); // Ensure the date is formatted using America/New York timezone using // the medium date format type. $this->assertEquals('Sat, 03/25/2017 - 06:30', $output[0]['#text']); } } Loading
config/schema/datetime_timezone.schema.yml +12 −0 Original line number Diff line number Diff line field.storage_settings.datetime_timezone: type: field.storage_settings.datetime label: 'Datetime Timezone field' field.value.datetime_timezone: type: field.value.datetime label: 'Default value' field.formatter.settings.datetime_timezone_default: type: mapping label: 'Date and timezone formatter' mapping: format_type: type: string label: 'The date format'
src/Plugin/Field/FieldFormatter/DateTimeTimezoneDefaultFormatter.php 0 → 100755 +49 −0 Original line number Diff line number Diff line <?php namespace Drupal\datetime_timezone\Plugin\Field\FieldFormatter; use Drupal\Core\Field\FieldItemListInterface; /** * Plugin implementation of the 'Default' formatter for 'datetime_timezone'. * * @FieldFormatter( * id = "datetime_timezone_default", * label = @Translation("Default"), * field_types = { * "datetime_timezone" * } * ) */ class DateTimeTimezoneDefaultFormatter extends DateTimeTimezoneFormatterBase { /** * {@inheritdoc} */ public function viewElements(FieldItemListInterface $items, $langcode) { $build = []; foreach ($items as $delta => $item) { if ($item->value) { // Create the ISO date in Universal Time. $date = $item->date; $iso_date = $date->format('Y-m-d\TH:i:s', ['timezone' => $item->timezone]) . 'Z'; $build[$delta] = [ '#theme' => 'time', '#text' => $this->formatDate($date, $item->timezone), '#attributes' => [ 'datetime' => $iso_date, ], '#cache' => [ 'contexts' => [ 'timezone', ], ], ]; } } return $build; } }
src/Plugin/Field/FieldFormatter/DateTimeTimezoneFormatterBase.php 0 → 100755 +120 −0 Original line number Diff line number Diff line <?php namespace Drupal\datetime_timezone\Plugin\Field\FieldFormatter; use Drupal\Core\Datetime\DrupalDateTime; use Drupal\Core\Field\FormatterBase; use Drupal\Core\Form\FormStateInterface; use Symfony\Component\DependencyInjection\ContainerInterface; abstract class DateTimeTimezoneFormatterBase extends FormatterBase { /** * The date formatter service. * * @var \Drupal\Core\Datetime\DateFormatterInterface */ protected $dateFormatter; /** * The date format entity storage. * * @var \Drupal\Core\Entity\EntityStorageInterface */ protected $dateFormatStorage; /** * {@inheritdoc} */ public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) { $instance = new static( $plugin_id, $plugin_definition, $configuration['field_definition'], $configuration['settings'], $configuration['label'], $configuration['view_mode'], $configuration['third_party_settings'] ); $instance->dateFormatter = $container->get('date.formatter'); $instance->dateFormatStorage = $container->get('entity_type.manager')->getStorage('date_format'); return $instance; } /** * {@inheritdoc} */ public static function defaultSettings() { return [ 'format_type' => 'medium', ] + parent::defaultSettings(); } /** * {@inheritdoc} */ public function settingsForm(array $form, FormStateInterface $form_state) { $form = parent::settingsForm($form, $form_state); $form['format_type'] = [ '#type' => 'select', '#title' => $this->t('Date format'), '#description' => $this->t('Choose a format for displaying the date. Be sure to set a format appropriate for the field, i.e. omitting time for a field that only has a date.'), '#options' => $this->getDateFormatOptions(), '#default_value' => $this->getSetting('format_type'), ]; return $form; } /** * {@inheritdoc} */ public function settingsSummary() { $summary = parent::settingsSummary(); $date = new DrupalDateTime(); $summary[] = $this->t('Format: @display', ['@display' => $this->formatDate($date)]); return $summary; } /** * Formats the date with the selected type. * * @param \Drupal\Core\Datetime\DrupalDateTime $date * The date object. * @param string|null $timezone * The timezone if we want to take it into account when rendering. * * @return string * The formatted date. */ protected function formatDate(DrupalDateTime $date, string $timezone = NULL): string { $format_type = $this->getSetting('format_type'); return $this->dateFormatter->format($date->getTimestamp(), $format_type, '', $timezone); } /** * Gets the date format options. * * @return array * An array of options to be used in the form. * * @see \Drupal\datetime\Plugin\Field\FieldFormatter\DateTimeDefaultFormatter */ protected function getDateFormatOptions() { $time = new DrupalDateTime(); $format_types = $this->dateFormatStorage->loadMultiple(); $options = []; foreach ($format_types as $type => $type_info) { $format = $this->dateFormatter->format($time->getTimestamp(), $type); $options[$type] = sprintf('%s (%s)', $type_info->label(), $format); } return $options; } }
src/Plugin/Field/FieldType/DateTimeTimezoneItem.php +1 −1 Original line number Diff line number Diff line Loading @@ -16,7 +16,7 @@ use Drupal\datetime\Plugin\Field\FieldType\DateTimeItem; * label = @Translation("Date with timezone"), * description = @Translation("Create and store date with timezone information."), * default_widget = "datetime_timezone", * default_formatter = "datetime_default", * default_formatter = "datetime_timezone_default", * list_class = "\Drupal\datetime\Plugin\Field\FieldType\DateTimeFieldItemList" * ) */ Loading
tests/src/Kernel/DateTimeTimezoneFormatterTest.php 0 → 100755 +95 −0 Original line number Diff line number Diff line <?php namespace Drupal\Tests\datetime_timezone\Kernel; use Drupal\Core\Datetime\DrupalDateTime; use Drupal\Core\Entity\Entity\EntityViewDisplay; use Drupal\datetime\Plugin\Field\FieldType\DateTimeItemInterface; use Drupal\entity_test\Entity\EntityTest; use Drupal\field\Entity\FieldConfig; use Drupal\field\Entity\FieldStorageConfig; use Drupal\KernelTests\KernelTestBase; /** * Test the default formatter. * * @group datetime_timezone */ class DateTimeTimezoneFormatterTest extends KernelTestBase { /** * Modules to enable. * * @var array */ public static $modules = [ 'user', 'system', 'field', 'text', 'entity_test', 'datetime', 'datetime_timezone', ]; /** * {@inheritdoc} */ protected function setUp() { parent::setUp(); $this->installConfig(['system']); $this->installEntitySchema('entity_test'); EntityViewDisplay::create([ 'targetEntityType' => 'entity_test', 'bundle' => 'entity_test', 'mode' => 'default', ])->save(); $field_storage = FieldStorageConfig::create([ 'field_name' => 'date', 'entity_type' => 'entity_test', 'type' => 'datetime_timezone', ]); $field_storage->save(); $field_config = FieldConfig::create([ 'field_storage' => $field_storage, 'bundle' => 'entity_test', ]); $field_config->save(); /* @var $entity_display_repository \Drupal\Core\Entity\EntityDisplayRepositoryInterface */ $entity_display_repository = \Drupal::service('entity_display.repository'); $entity_display_repository->getViewDisplay('entity_test', 'entity_test', 'default') ->setComponent('date', [ 'type' => 'datetime_timezone_default', ]) ->save(); } /** * Ensure the field is rendered in the correct timezone. */ public function testRenderedInCorrectTimezone() { $timezone = 'America/New_York'; $date = new DrupalDateTime('2017-03-25 10:30:00', 'UTC'); $entity = EntityTest::create([ 'date' => [ 'value' => $date->format(DateTimeItemInterface::DATETIME_STORAGE_FORMAT), 'timezone' => $timezone, ], ]); $entity->save(); // Render the field. $output = $entity->date->view([]); // Ensure the date is formatted using America/New York timezone using // the medium date format type. $this->assertEquals('Sat, 03/25/2017 - 06:30', $output[0]['#text']); } }