コード例 #1
0
 /**
  * {@inheritdoc}
  */
 public function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, FormStateInterface $form_state)
 {
     $date_format = DateFormat::load('html_date')->getPattern();
     $time_format = DateFormat::load('html_time')->getPattern();
     $default_value = isset($items[$delta]->value) ? DrupalDateTime::createFromTimestamp($items[$delta]->value) : '';
     $element['value'] = $element + array('#type' => 'datetime', '#default_value' => $default_value, '#date_year_range' => '1902:2037');
     $element['value']['#description'] = $this->t('Format: %format. Leave blank to use the time of form submission.', array('%format' => Datetime::formatExample($date_format . ' ' . $time_format)));
     return $element;
 }
コード例 #2
0
 /**
  * Tests the display of dates and time when user-configurable time zones are set.
  */
 function testUserTimeZone()
 {
     // Setup date/time settings for Los Angeles time.
     $this->config('system.date')->set('timezone.user.configurable', 1)->set('timezone.default', 'America/Los_Angeles')->save();
     DateFormat::load('medium')->setPattern('Y-m-d H:i T')->save();
     // Create a user account and login.
     $web_user = $this->drupalCreateUser();
     $this->drupalLogin($web_user);
     // Create some nodes with different authored-on dates.
     // Two dates in PST (winter time):
     $date1 = '2007-03-09 21:00:00 -0800';
     $date2 = '2007-03-11 01:00:00 -0800';
     // One date in PDT (summer time):
     $date3 = '2007-03-20 21:00:00 -0700';
     $this->drupalCreateContentType(array('type' => 'article'));
     $node1 = $this->drupalCreateNode(array('created' => strtotime($date1), 'type' => 'article'));
     $node2 = $this->drupalCreateNode(array('created' => strtotime($date2), 'type' => 'article'));
     $node3 = $this->drupalCreateNode(array('created' => strtotime($date3), 'type' => 'article'));
     // Confirm date format and time zone.
     $this->drupalGet('node/' . $node1->id());
     $this->assertText('2007-03-09 21:00 PST', 'Date should be PST.');
     $this->drupalGet('node/' . $node2->id());
     $this->assertText('2007-03-11 01:00 PST', 'Date should be PST.');
     $this->drupalGet('node/' . $node3->id());
     $this->assertText('2007-03-20 21:00 PDT', 'Date should be PDT.');
     // Change user time zone to Santiago time.
     $edit = array();
     $edit['mail'] = $web_user->getEmail();
     $edit['timezone'] = 'America/Santiago';
     $this->drupalPostForm("user/" . $web_user->id() . "/edit", $edit, t('Save'));
     $this->assertText(t('The changes have been saved.'), 'Time zone changed to Santiago time.');
     // Confirm date format and time zone.
     $this->drupalGet('node/' . $node1->id());
     $this->assertText('2007-03-10 02:00 CLST', 'Date should be Chile summer time; five hours ahead of PST.');
     $this->drupalGet('node/' . $node2->id());
     $this->assertText('2007-03-11 05:00 CLT', 'Date should be Chile time; four hours ahead of PST');
     $this->drupalGet('node/' . $node3->id());
     $this->assertText('2007-03-21 00:00 CLT', 'Date should be Chile time; three hours ahead of PDT.');
     // Ensure that anonymous users also use the default timezone.
     $this->drupalLogout();
     $this->drupalGet('node/' . $node1->id());
     $this->assertText('2007-03-09 21:00 PST', 'Date should be PST.');
     $this->drupalGet('node/' . $node2->id());
     $this->assertText('2007-03-11 01:00 PST', 'Date should be PST.');
     $this->drupalGet('node/' . $node3->id());
     $this->assertText('2007-03-20 21:00 PDT', 'Date should be PDT.');
     // Format a date without accessing the current user at all and
     // ensure that it uses the default timezone.
     $this->drupalGet('/system-test/date');
     $this->assertText('2016-01-13 08:29 PST', 'Date should be PST.');
 }
コード例 #3
0
 /**
  * Tests the Drupal 6 date formats to Drupal 8 migration.
  */
 public function testDateFormats()
 {
     $short_date_format = DateFormat::load('short');
     $this->assertIdentical('\\S\\H\\O\\R\\T m/d/Y - H:i', $short_date_format->getPattern());
     $medium_date_format = DateFormat::load('medium');
     $this->assertIdentical('\\M\\E\\D\\I\\U\\M D, m/d/Y - H:i', $medium_date_format->getPattern());
     $long_date_format = DateFormat::load('long');
     $this->assertIdentical('\\L\\O\\N\\G l, F j, Y - H:i', $long_date_format->getPattern());
     // Test that we can re-import using the EntityDateFormat destination.
     Database::getConnection('default', 'migrate')->update('variable')->fields(array('value' => serialize('\\S\\H\\O\\R\\T d/m/Y - H:i')))->condition('name', 'date_format_short')->execute();
     $migration = $this->getMigration('d6_date_formats');
     \Drupal::database()->truncate($migration->getIdMap()->mapTableName())->execute();
     $this->executeMigration($migration);
     $short_date_format = DateFormat::load('short');
     $this->assertIdentical('\\S\\H\\O\\R\\T d/m/Y - H:i', $short_date_format->getPattern());
 }
コード例 #4
0
 /**
  * {@inheritdoc}
  */
 public function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, FormStateInterface $form_state)
 {
     $element = parent::formElement($items, $delta, $element, $form, $form_state);
     // Remove 'Leave blank to use the time of form submission' which is in the
     // #description inherited from TimestampDatetimeWidget. The text here is not
     // used because it is entirely replaced in scheduler_form_node_form_alter()
     // However the widget is generic and may be used elsewhere in future.
     $date_format = DateFormat::load('html_date')->getPattern();
     $time_format = DateFormat::load('html_time')->getPattern();
     $element['value']['#description'] = $this->t('Format: %format. Leave blank for no date.', array('%format' => Datetime::formatExample($date_format . ' ' . $time_format)));
     // Set the callback function to allow interception of the submitted user
     // input and add the default time if needed. It is too late to try this in
     // function massageFormValues as the validation has already been done.
     $element['value']['#value_callback'] = array($this, 'valueCallback');
     return $element;
 }
コード例 #5
0
 /**
  * @cover \Drupal\rules\Plugin\TypedDataFilter\FormatDateFilter
  */
 public function testFormatDateFilter()
 {
     $filter = $this->dataFilterManager->createInstance('format_date');
     $data = $this->typedDataManager->create(DataDefinition::create('timestamp'), 3700);
     $this->assertTrue($filter->canFilter($data->getDataDefinition()));
     $this->assertFalse($filter->canFilter(DataDefinition::create('any')));
     $this->assertEquals('string', $filter->filtersTo($data->getDataDefinition(), [])->getDataType());
     $fails = $filter->validateArguments($data->getDataDefinition(), []);
     $this->assertEquals(0, count($fails));
     $fails = $filter->validateArguments($data->getDataDefinition(), ['medium']);
     $this->assertEquals(0, count($fails));
     $fails = $filter->validateArguments($data->getDataDefinition(), ['invalid-format']);
     $this->assertEquals(1, count($fails));
     $fails = $filter->validateArguments($data->getDataDefinition(), ['custom']);
     $this->assertEquals(1, count($fails));
     $fails = $filter->validateArguments($data->getDataDefinition(), ['custom', 'Y']);
     $this->assertEquals(0, count($fails));
     /** @var \Drupal\Core\Datetime\DateFormatterInterface $date_formatter */
     $date_formatter = $this->container->get('date.formatter');
     $this->assertEquals($date_formatter->format(3700), $filter->filter($data->getDataDefinition(), $data->getValue(), []));
     $this->assertEquals($date_formatter->format(3700, 'short'), $filter->filter($data->getDataDefinition(), $data->getValue(), ['short']));
     $this->assertEquals('1970', $filter->filter($data->getDataDefinition(), $data->getValue(), ['custom', 'Y']));
     // Verify the filter works with non-timestamp data as well.
     $data = $this->typedDataManager->create(DataDefinition::create('datetime_iso8601'), "1970-01-01T10:10:10+00:00");
     $this->assertTrue($filter->canFilter($data->getDataDefinition()));
     $this->assertEquals('string', $filter->filtersTo($data->getDataDefinition(), [])->getDataType());
     $this->assertEquals('1970', $filter->filter($data->getDataDefinition(), $data->getValue(), ['custom', 'Y']));
     // Test cache dependencies of date format config entities are added in.
     $metadata = new BubbleableMetadata();
     $filter->filter($data->getDataDefinition(), $data->getValue(), ['short'], $metadata);
     $this->assertEquals(DateFormat::load('short')->getCacheTags(), $metadata->getCacheTags());
     $metadata = new BubbleableMetadata();
     $filter->filter($data->getDataDefinition(), $data->getValue(), ['custom', 'Y'], $metadata);
     $this->assertEquals([], $metadata->getCacheTags());
 }
コード例 #6
0
ファイル: Datetime.php プロジェクト: papillon-cendre/d8
 /**
  * Retrieves the right format for a HTML5 time element.
  *
  * The format is important because these elements will not work with any other
  * format.
  *
  * @param string $element
  *   The $element to assess.
  *
  * @return string
  *   Returns the right format for the time element, or the original format
  *   if this is not a HTML5 element.
  */
 protected static function getHtml5TimeFormat($element)
 {
     switch ($element['#date_time_element']) {
         case 'time':
             return DateFormat::load('html_time')->getPattern();
         default:
             return $element['#date_time_format'];
     }
 }
コード例 #7
0
 /**
  * Tests all-day field.
  */
 public function testAlldayRangeField()
 {
     $field_name = $this->fieldStorage->getName();
     // Ensure field is set to a all-day field.
     $this->fieldStorage->setSetting('datetime_type', DateRangeItem::DATETIME_TYPE_ALLDAY);
     $this->fieldStorage->save();
     // Display creation form.
     $this->drupalGet('entity_test/add');
     $this->assertFieldByName("{$field_name}[0][value][date]", '', 'Start date element found.');
     $this->assertFieldByName("{$field_name}[0][end_value][date]", '', 'End date element found.');
     $this->assertFieldByXPath('//*[@id="edit-' . $field_name . '-wrapper"]/h4[contains(@class, "js-form-required")]', TRUE, 'Required markup found');
     $this->assertNoFieldByName("{$field_name}[0][value][time]", '', 'Start time element not found.');
     $this->assertNoFieldByName("{$field_name}[0][end_value][time]", '', 'End time element not found.');
     // Build up dates in the proper timezone.
     $value = '2012-12-31 00:00:00';
     $start_date = new DrupalDateTime($value, timezone_open(drupal_get_user_timezone()));
     $end_value = '2013-06-06 23:59:59';
     $end_date = new DrupalDateTime($end_value, timezone_open(drupal_get_user_timezone()));
     // Submit a valid date and ensure it is accepted.
     $date_format = DateFormat::load('html_date')->getPattern();
     $time_format = DateFormat::load('html_time')->getPattern();
     $edit = array("{$field_name}[0][value][date]" => $start_date->format($date_format), "{$field_name}[0][end_value][date]" => $end_date->format($date_format));
     $this->drupalPostForm(NULL, $edit, t('Save'));
     preg_match('|entity_test/manage/(\\d+)|', $this->url, $match);
     $id = $match[1];
     $this->assertText(t('entity_test @id has been created.', array('@id' => $id)));
     $this->assertRaw($start_date->format($date_format));
     $this->assertNoRaw($start_date->format($time_format));
     $this->assertRaw($end_date->format($date_format));
     $this->assertNoRaw($end_date->format($time_format));
     // Verify that the default formatter works.
     $this->displayOptions['settings'] = ['format_type' => 'long', 'separator' => 'THESEPARATOR'] + $this->defaultSettings;
     entity_get_display($this->field->getTargetEntityTypeId(), $this->field->getTargetBundle(), 'full')->setComponent($field_name, $this->displayOptions)->save();
     $start_expected = $this->dateFormatter->format($start_date->getTimestamp(), 'long');
     $start_expected_iso = $this->dateFormatter->format($start_date->getTimestamp(), 'custom', 'Y-m-d\\TH:i:s\\Z', 'UTC');
     $end_expected = $this->dateFormatter->format($end_date->getTimestamp(), 'long');
     $end_expected_iso = $this->dateFormatter->format($end_date->getTimestamp(), 'custom', 'Y-m-d\\TH:i:s\\Z', 'UTC');
     $this->renderTestEntity($id);
     $this->assertFieldByXPath('//time[@datetime="' . $start_expected_iso . '"]', $start_expected, new FormattableMarkup('Formatted date field using %value format displayed as %expected with %expected_iso attribute.', ['%value' => 'long', '%expected' => $start_expected, '%expected_iso' => $start_expected_iso]));
     $this->assertFieldByXPath('//time[@datetime="' . $end_expected_iso . '"]', $end_expected, new FormattableMarkup('Formatted date field using %value format displayed as %expected with %expected_iso attribute.', ['%value' => 'long', '%expected' => $end_expected, '%expected_iso' => $end_expected_iso]));
     $this->assertText(' THESEPARATOR ', 'Found proper separator');
     // Verify that the plain formatter works.
     $this->displayOptions['type'] = 'daterange_plain';
     $this->displayOptions['settings'] = $this->defaultSettings;
     entity_get_display($this->field->getTargetEntityTypeId(), $this->field->getTargetBundle(), 'full')->setComponent($field_name, $this->displayOptions)->save();
     $expected = $start_date->format(DATETIME_DATETIME_STORAGE_FORMAT) . ' - ' . $end_date->format(DATETIME_DATETIME_STORAGE_FORMAT);
     $this->renderTestEntity($id);
     $this->assertText($expected, new FormattableMarkup('Formatted date field using plain format displayed as %expected.', array('%expected' => $expected)));
     // Verify that the custom formatter works.
     $this->displayOptions['type'] = 'daterange_custom';
     $this->displayOptions['settings'] = array('date_format' => 'm/d/Y') + $this->defaultSettings;
     entity_get_display($this->field->getTargetEntityTypeId(), $this->field->getTargetBundle(), 'full')->setComponent($field_name, $this->displayOptions)->save();
     $expected = $start_date->format($this->displayOptions['settings']['date_format']) . ' - ' . $end_date->format($this->displayOptions['settings']['date_format']);
     $this->renderTestEntity($id);
     $this->assertText($expected, new FormattableMarkup('Formatted date field using daterange_custom format displayed as %expected.', array('%expected' => $expected)));
     // Verify that the 'timezone_override' setting works.
     $this->displayOptions['type'] = 'daterange_custom';
     $this->displayOptions['settings'] = ['date_format' => 'm/d/Y g:i:s A', 'timezone_override' => 'America/New_York'] + $this->defaultSettings;
     entity_get_display($this->field->getTargetEntityTypeId(), $this->field->getTargetBundle(), 'full')->setComponent($field_name, $this->displayOptions)->save();
     $expected = $start_date->format($this->displayOptions['settings']['date_format'], ['timezone' => 'America/New_York']);
     $expected .= ' - ' . $end_date->format($this->displayOptions['settings']['date_format'], ['timezone' => 'America/New_York']);
     $this->renderTestEntity($id);
     $this->assertText($expected, new FormattableMarkup('Formatted date field using daterange_custom format displayed as %expected.', array('%expected' => $expected)));
     // Test formatters when start date and end date are the same
     $this->drupalGet('entity_test/add');
     $value = '2012-12-31 00:00:00';
     $start_date = new DrupalDateTime($value, timezone_open(drupal_get_user_timezone()));
     $end_value = '2012-12-31 23:59:59';
     $end_date = new DrupalDateTime($end_value, timezone_open(drupal_get_user_timezone()));
     $date_format = DateFormat::load('html_date')->getPattern();
     $time_format = DateFormat::load('html_time')->getPattern();
     $edit = array("{$field_name}[0][value][date]" => $start_date->format($date_format), "{$field_name}[0][end_value][date]" => $start_date->format($date_format));
     $this->drupalPostForm(NULL, $edit, t('Save'));
     preg_match('|entity_test/manage/(\\d+)|', $this->url, $match);
     $id = $match[1];
     $this->assertText(t('entity_test @id has been created.', array('@id' => $id)));
     $this->displayOptions = ['type' => 'daterange_default', 'label' => 'hidden', 'settings' => ['format_type' => 'long', 'separator' => 'THESEPARATOR'] + $this->defaultSettings];
     entity_get_display($this->field->getTargetEntityTypeId(), $this->field->getTargetBundle(), 'full')->setComponent($field_name, $this->displayOptions)->save();
     $start_expected = $this->dateFormatter->format($start_date->getTimestamp(), 'long');
     $start_expected_iso = $this->dateFormatter->format($start_date->getTimestamp(), 'custom', 'Y-m-d\\TH:i:s\\Z', 'UTC');
     $end_expected = $this->dateFormatter->format($end_date->getTimestamp(), 'long');
     $end_expected_iso = $this->dateFormatter->format($end_date->getTimestamp(), 'custom', 'Y-m-d\\TH:i:s\\Z', 'UTC');
     $this->renderTestEntity($id);
     $this->assertFieldByXPath('//time[@datetime="' . $start_expected_iso . '"]', $start_expected, new FormattableMarkup('Formatted date field using %value format displayed as %expected with %expected_iso attribute.', ['%value' => 'long', '%expected' => $start_expected, '%expected_iso' => $start_expected_iso]));
     $this->assertFieldByXPath('//time[@datetime="' . $end_expected_iso . '"]', $end_expected, new FormattableMarkup('Formatted date field using %value format displayed as %expected with %expected_iso attribute.', ['%value' => 'long', '%expected' => $end_expected, '%expected_iso' => $end_expected_iso]));
     $this->assertText(' THESEPARATOR ', 'Found proper separator');
     $this->displayOptions['type'] = 'daterange_plain';
     entity_get_display($this->field->getTargetEntityTypeId(), $this->field->getTargetBundle(), 'full')->setComponent($field_name, $this->displayOptions)->save();
     $expected = $start_date->format(DATETIME_DATETIME_STORAGE_FORMAT) . ' THESEPARATOR ' . $end_date->format(DATETIME_DATETIME_STORAGE_FORMAT);
     $this->renderTestEntity($id);
     $this->assertText($expected, new FormattableMarkup('Formatted date field using plain format displayed as %expected.', array('%expected' => $expected)));
     $this->assertText(' THESEPARATOR ', 'Found proper separator');
     $this->displayOptions['type'] = 'daterange_custom';
     $this->displayOptions['settings']['date_format'] = 'm/d/Y';
     entity_get_display($this->field->getTargetEntityTypeId(), $this->field->getTargetBundle(), 'full')->setComponent($field_name, $this->displayOptions)->save();
     $expected = $start_date->format($this->displayOptions['settings']['date_format']) . ' THESEPARATOR ' . $end_date->format($this->displayOptions['settings']['date_format']);
     $this->renderTestEntity($id);
     $this->assertText($expected, new FormattableMarkup('Formatted date field using daterange_custom format displayed as %expected.', array('%expected' => $expected)));
     $this->assertText(' THESEPARATOR ', 'Found proper separator');
 }
コード例 #8
0
 /**
  * @cover replacePlaceHolders
  */
 public function testBubbleableMetadata()
 {
     // Make sure the bubbleable metadata added by the fetcher is properly passed
     // though.
     $bubbleable_metadata = new BubbleableMetadata();
     // Save the node, so it gets a cache tag.
     $this->node->save();
     $this->placeholderResolver->replacePlaceHolders('test {{node.field_integer}}', ['node' => $this->node->getTypedData()], $bubbleable_metadata);
     $expected = ['node:' . $this->node->id()];
     $this->assertEquals($expected, $bubbleable_metadata->getCacheTags());
     // Ensure cache tags of filters are added in.
     $bubbleable_metadata = new BubbleableMetadata();
     $this->placeholderResolver->replacePlaceHolders("test {{ node.created.value | format_date('medium') }}", ['node' => $this->node->getTypedData()], $bubbleable_metadata);
     $expected = Cache::mergeTags(['node:' . $this->node->id()], DateFormat::load('medium')->getCacheTags());
     $this->assertEquals($expected, $bubbleable_metadata->getCacheTags());
 }
コード例 #9
0
ファイル: DateTimeTest.php プロジェクト: eigentor/tommiblog
 /**
  * Test date format configuration.
  */
 function testDateFormatConfiguration()
 {
     // Confirm 'no custom date formats available' message appears.
     $this->drupalGet('admin/config/regional/date-time');
     // Add custom date format.
     $this->clickLink(t('Add format'));
     $date_format_id = strtolower($this->randomMachineName(8));
     $name = ucwords($date_format_id);
     $date_format = 'd.m.Y - H:i';
     $edit = array('id' => $date_format_id, 'label' => $name, 'date_format_pattern' => $date_format);
     $this->drupalPostForm('admin/config/regional/date-time/formats/add', $edit, t('Add format'));
     $this->assertUrl(\Drupal::url('entity.date_format.collection', [], ['absolute' => TRUE]), [], 'Correct page redirection.');
     $this->assertText(t('Custom date format added.'), 'Date format added confirmation message appears.');
     $this->assertText($name, 'Custom date format appears in the date format list.');
     $this->assertText(t('Delete'), 'Delete link for custom date format appears.');
     // Edit the custom date format and re-save without editing the format.
     $this->drupalGet('admin/config/regional/date-time');
     $this->clickLink(t('Edit'));
     $this->drupalPostForm(NULL, NULL, t('Save format'));
     $this->assertUrl('admin/config/regional/date-time', array('absolute' => TRUE), 'Correct page redirection.');
     $this->assertText(t('Custom date format updated.'), 'Custom date format successfully updated.');
     // Edit custom date format.
     $this->drupalGet('admin/config/regional/date-time');
     $this->clickLink(t('Edit'));
     $edit = array('date_format_pattern' => 'Y m');
     $this->drupalPostForm($this->getUrl(), $edit, t('Save format'));
     $this->assertUrl(\Drupal::url('entity.date_format.collection', [], ['absolute' => TRUE]), [], 'Correct page redirection.');
     $this->assertText(t('Custom date format updated.'), 'Custom date format successfully updated.');
     // Delete custom date format.
     $this->clickLink(t('Delete'));
     $this->drupalPostForm('admin/config/regional/date-time/formats/manage/' . $date_format_id . '/delete', array(), t('Delete'));
     $this->assertUrl(\Drupal::url('entity.date_format.collection', [], ['absolute' => TRUE]), [], 'Correct page redirection.');
     $this->assertRaw(t('The date format %format has been deleted.', array('%format' => $name)), 'Custom date format removed.');
     // Make sure the date does not exist in config.
     $date_format = DateFormat::load($date_format_id);
     $this->assertFalse($date_format);
     // Add a new date format with an existing format.
     $date_format_id = strtolower($this->randomMachineName(8));
     $name = ucwords($date_format_id);
     $date_format = 'Y';
     $edit = array('id' => $date_format_id, 'label' => $name, 'date_format_pattern' => $date_format);
     $this->drupalPostForm('admin/config/regional/date-time/formats/add', $edit, t('Add format'));
     $this->assertUrl(\Drupal::url('entity.date_format.collection', [], ['absolute' => TRUE]), [], 'Correct page redirection.');
     $this->assertText(t('Custom date format added.'), 'Date format added confirmation message appears.');
     $this->assertText($name, 'Custom date format appears in the date format list.');
     $this->assertText(t('Delete'), 'Delete link for custom date format appears.');
     $date_format = DateFormat::create(array('id' => 'xss_short', 'label' => 'XSS format', 'pattern' => '\\<\\s\\c\\r\\i\\p\\t\\>\\a\\l\\e\\r\\t\\(\'\\X\\S\\S\'\\)\\;\\<\\/\\s\\c\\r\\i\\p\\t\\>'));
     $date_format->save();
     $this->drupalGet(Url::fromRoute('entity.date_format.collection'));
     $this->assertEscaped("<script>alert('XSS');</script>", 'The date format was properly escaped');
     // Add a new date format with HTML in it.
     $date_format_id = strtolower($this->randomMachineName(8));
     $name = ucwords($date_format_id);
     $date_format = '& \\<\\e\\m\\>Y\\<\\/\\e\\m\\>';
     $edit = array('id' => $date_format_id, 'label' => $name, 'date_format_pattern' => $date_format);
     $this->drupalPostForm('admin/config/regional/date-time/formats/add', $edit, t('Add format'));
     $this->assertUrl(\Drupal::url('entity.date_format.collection', [], ['absolute' => TRUE]), [], 'Correct page redirection.');
     $this->assertText(t('Custom date format added.'), 'Date format added confirmation message appears.');
     $this->assertText($name, 'Custom date format appears in the date format list.');
     $this->assertEscaped('<em>' . date("Y") . '</em>');
 }
コード例 #10
0
 /**
  * Tests date and time field.
  */
 function testDatetimeField()
 {
     $field_name = $this->fieldStorage->getName();
     // Change the field to a datetime field.
     $this->fieldStorage->setSetting('datetime_type', 'datetime');
     $this->fieldStorage->save();
     // Display creation form.
     $this->drupalGet('entity_test/add');
     $this->assertFieldByName("{$field_name}[0][value][date]", '', 'Date element found.');
     $this->assertFieldByName("{$field_name}[0][value][time]", '', 'Time element found.');
     // Build up a date in the UTC timezone.
     $value = '2012-12-31 00:00:00';
     $date = new DrupalDateTime($value, 'UTC');
     // Update the timezone to the system default.
     $date->setTimezone(timezone_open(drupal_get_user_timezone()));
     // Submit a valid date and ensure it is accepted.
     $date_format = DateFormat::load('html_date')->getPattern();
     $time_format = DateFormat::load('html_time')->getPattern();
     $edit = array("{$field_name}[0][value][date]" => $date->format($date_format), "{$field_name}[0][value][time]" => $date->format($time_format));
     $this->drupalPostForm(NULL, $edit, t('Save'));
     preg_match('|entity_test/manage/(\\d+)|', $this->url, $match);
     $id = $match[1];
     $this->assertText(t('entity_test @id has been created.', array('@id' => $id)));
     $this->assertRaw($date->format($date_format));
     $this->assertRaw($date->format($time_format));
     // Verify that the date is output according to the formatter settings.
     $options = array('format_type' => array('short', 'medium', 'long'));
     foreach ($options as $setting => $values) {
         foreach ($values as $new_value) {
             // Update the entity display settings.
             $this->displayOptions['settings'] = array($setting => $new_value) + $this->defaultSettings;
             entity_get_display($this->field->getTargetEntityTypeId(), $this->field->getTargetBundle(), 'full')->setComponent($field_name, $this->displayOptions)->save();
             $this->renderTestEntity($id);
             switch ($setting) {
                 case 'format_type':
                     // Verify that a date is displayed.
                     $expected = format_date($date->getTimestamp(), $new_value);
                     $expected_iso = format_date($date->getTimestamp(), 'custom', 'Y-m-d\\TH:i:s\\Z', 'UTC');
                     $this->renderTestEntity($id);
                     $this->assertFieldByXPath('//time[@datetime="' . $expected_iso . '"]', $expected, SafeMarkup::format('Formatted date field using %value format displayed as %expected with %expected_iso attribute.', array('%value' => $new_value, '%expected' => $expected, '%expected_iso' => $expected_iso)));
                     break;
             }
         }
     }
     // Verify that the plain formatter works.
     $this->displayOptions['type'] = 'datetime_plain';
     $this->displayOptions['settings'] = $this->defaultSettings;
     entity_get_display($this->field->getTargetEntityTypeId(), $this->field->getTargetBundle(), 'full')->setComponent($field_name, $this->displayOptions)->save();
     $expected = $date->format(DATETIME_DATETIME_STORAGE_FORMAT);
     $this->renderTestEntity($id);
     $this->assertText($expected, SafeMarkup::format('Formatted date field using plain format displayed as %expected.', array('%expected' => $expected)));
     // Verify that the 'datetime_custom' formatter works.
     $this->displayOptions['type'] = 'datetime_custom';
     $this->displayOptions['settings'] = array('date_format' => 'm/d/Y g:i:s A') + $this->defaultSettings;
     entity_get_display($this->field->getTargetEntityTypeId(), $this->field->getTargetBundle(), 'full')->setComponent($field_name, $this->displayOptions)->save();
     $expected = $date->format($this->displayOptions['settings']['date_format']);
     $this->renderTestEntity($id);
     $this->assertText($expected, SafeMarkup::format('Formatted date field using datetime_custom format displayed as %expected.', array('%expected' => $expected)));
     // Verify that the 'timezone_override' setting works.
     $this->displayOptions['type'] = 'datetime_custom';
     $this->displayOptions['settings'] = array('date_format' => 'm/d/Y g:i:s A', 'timezone_override' => 'America/New_York') + $this->defaultSettings;
     entity_get_display($this->field->getTargetEntityTypeId(), $this->field->getTargetBundle(), 'full')->setComponent($field_name, $this->displayOptions)->save();
     $expected = $date->format($this->displayOptions['settings']['date_format'], array('timezone' => 'America/New_York'));
     $this->renderTestEntity($id);
     $this->assertText($expected, SafeMarkup::format('Formatted date field using datetime_custom format displayed as %expected.', array('%expected' => $expected)));
     // Verify that the 'datetime_time_ago' formatter works for intervals in the
     // past.  First update the test entity so that the date difference always
     // has the same interval.  Since the database always stores UTC, and the
     // interval will use this, force the test date to use UTC and not the local
     // or user timezome.
     $timestamp = REQUEST_TIME - 87654321;
     $entity = EntityTest::load($id);
     $field_name = $this->fieldStorage->getName();
     $date = DrupalDateTime::createFromTimestamp($timestamp, 'UTC');
     $entity->{$field_name}->value = $date->format(DATETIME_DATETIME_STORAGE_FORMAT);
     $entity->save();
     $this->displayOptions['type'] = 'datetime_time_ago';
     $this->displayOptions['settings'] = array('future_format' => '@interval from now', 'past_format' => '@interval earlier', 'granularity' => 3);
     entity_get_display($this->field->getTargetEntityTypeId(), $this->field->getTargetBundle(), 'full')->setComponent($field_name, $this->displayOptions)->save();
     $expected = SafeMarkup::format($this->displayOptions['settings']['past_format'], ['@interval' => $this->dateFormatter->formatTimeDiffSince($timestamp, ['granularity' => $this->displayOptions['settings']['granularity']])]);
     $this->renderTestEntity($id);
     $this->assertText($expected, SafeMarkup::format('Formatted date field using datetime_time_ago format displayed as %expected.', array('%expected' => $expected)));
     // Verify that the 'datetime_time_ago' formatter works for intervals in the
     // future.  First update the test entity so that the date difference always
     // has the same interval.  Since the database always stores UTC, and the
     // interval will use this, force the test date to use UTC and not the local
     // or user timezome.
     $timestamp = REQUEST_TIME + 87654321;
     $entity = EntityTest::load($id);
     $field_name = $this->fieldStorage->getName();
     $date = DrupalDateTime::createFromTimestamp($timestamp, 'UTC');
     $entity->{$field_name}->value = $date->format(DATETIME_DATETIME_STORAGE_FORMAT);
     $entity->save();
     entity_get_display($this->field->getTargetEntityTypeId(), $this->field->getTargetBundle(), 'full')->setComponent($field_name, $this->displayOptions)->save();
     $expected = SafeMarkup::format($this->displayOptions['settings']['future_format'], ['@interval' => $this->dateFormatter->formatTimeDiffUntil($timestamp, ['granularity' => $this->displayOptions['settings']['granularity']])]);
     $this->renderTestEntity($id);
     $this->assertText($expected, SafeMarkup::format('Formatted date field using datetime_time_ago format displayed as %expected.', array('%expected' => $expected)));
 }