summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNathaniel Catchpole2017-01-26 11:17:57 (GMT)
committerNathaniel Catchpole2017-01-26 11:17:57 (GMT)
commita92f817f22b0a08af1aeac05179597f88a5d205c (patch)
treeb62c7e0cce9a1f2bdf8cf020513ebf8313df5cc6
parent3af641f19149b32a7b13f08a2395f9fbf5e5bb35 (diff)
Issue #2829848 by xjm, mpdonadio, alexpott: Random test failure in DateRangeFieldTest
-rw-r--r--core/modules/datetime/src/DateTimeComputed.php17
-rw-r--r--core/modules/datetime_range/tests/src/Kernel/DateRangeItemTest.php105
2 files changed, 121 insertions, 1 deletions
diff --git a/core/modules/datetime/src/DateTimeComputed.php b/core/modules/datetime/src/DateTimeComputed.php
index 6939994..9320baf 100644
--- a/core/modules/datetime/src/DateTimeComputed.php
+++ b/core/modules/datetime/src/DateTimeComputed.php
@@ -2,6 +2,7 @@
namespace Drupal\datetime;
+use Drupal\datetime\Plugin\Field\FieldType\DateTimeItem;
use Drupal\Core\Datetime\DrupalDateTime;
use Drupal\Core\TypedData\DataDefinitionInterface;
use Drupal\Core\TypedData\TypedDataInterface;
@@ -40,14 +41,28 @@ class DateTimeComputed extends TypedData {
return $this->date;
}
+ /** @var \Drupal\Core\Field\FieldItemInterface $item */
$item = $this->getParent();
$value = $item->{($this->definition->getSetting('date source'))};
- $storage_format = $item->getFieldDefinition()->getSetting('datetime_type') == 'date' ? DATETIME_DATE_STORAGE_FORMAT : DATETIME_DATETIME_STORAGE_FORMAT;
+ $datetime_type = $item->getFieldDefinition()->getSetting('datetime_type');
+ $storage_format = $datetime_type === DateTimeItem::DATETIME_TYPE_DATE ? DATETIME_DATE_STORAGE_FORMAT : DATETIME_DATETIME_STORAGE_FORMAT;
try {
$date = DrupalDateTime::createFromFormat($storage_format, $value, DATETIME_STORAGE_TIMEZONE);
if ($date instanceof DrupalDateTime && !$date->hasErrors()) {
$this->date = $date;
+ // If the format did not include an explicit time portion, then the
+ // time will be set from the current time instead. For consistency, we
+ // set the time to 12:00:00 UTC for date-only fields. This is used so
+ // that the local date portion is the same, across nearly all time
+ // zones.
+ // @see datetime_date_default_time()
+ // @see http://php.net/manual/en/datetime.createfromformat.php
+ // @todo Update comment and/or code per the chosen solution in
+ // https://www.drupal.org/node/2830094
+ if ($datetime_type === DateTimeItem::DATETIME_TYPE_DATE) {
+ $this->date->setTime(12, 0, 0);
+ }
}
}
catch (\Exception $e) {
diff --git a/core/modules/datetime_range/tests/src/Kernel/DateRangeItemTest.php b/core/modules/datetime_range/tests/src/Kernel/DateRangeItemTest.php
new file mode 100644
index 0000000..67e1b9d
--- /dev/null
+++ b/core/modules/datetime_range/tests/src/Kernel/DateRangeItemTest.php
@@ -0,0 +1,105 @@
+<?php
+
+namespace Drupal\Tests\datetime_range\Kernel;
+
+use Drupal\Component\Utility\Unicode;
+use Drupal\Core\Entity\Entity\EntityViewDisplay;
+use Drupal\datetime_range\Plugin\Field\FieldType\DateRangeItem;
+use Drupal\entity_test\Entity\EntityTest;
+use Drupal\field\Entity\FieldConfig;
+use Drupal\field\Entity\FieldStorageConfig;
+use Drupal\Tests\field\Kernel\FieldKernelTestBase;
+
+/**
+ * Test datetime range field type via API.
+ *
+ * @group datetime
+ */
+class DateRangeItemTest extends FieldKernelTestBase {
+
+ /**
+ * A field storage to use in this test class.
+ *
+ * @var \Drupal\field\Entity\FieldStorageConfig
+ */
+ protected $fieldStorage;
+
+ /**
+ * The field used in this test class.
+ *
+ * @var \Drupal\field\Entity\FieldConfig
+ */
+ protected $field;
+
+ /**
+ * {@inheritdoc}
+ */
+ public static $modules = [
+ 'datetime',
+ 'datetime_range',
+ ];
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function setUp() {
+ parent::setUp();
+
+ // Add a datetime range field.
+ $this->fieldStorage = FieldStorageConfig::create([
+ 'field_name' => Unicode::strtolower($this->randomMachineName()),
+ 'entity_type' => 'entity_test',
+ 'type' => 'daterange',
+ 'settings' => ['datetime_type' => DateRangeItem::DATETIME_TYPE_DATE],
+ ]);
+ $this->fieldStorage->save();
+
+ $this->field = FieldConfig::create([
+ 'field_storage' => $this->fieldStorage,
+ 'bundle' => 'entity_test',
+ 'required' => TRUE,
+ ]);
+ $this->field->save();
+
+ $display_options = [
+ 'type' => 'daterange_default',
+ 'label' => 'hidden',
+ 'settings' => [
+ 'format_type' => 'fallback',
+ 'separator' => 'UNTRANSLATED',
+ ],
+ ];
+ EntityViewDisplay::create([
+ 'targetEntityType' => $this->field->getTargetEntityTypeId(),
+ 'bundle' => $this->field->getTargetBundle(),
+ 'mode' => 'default',
+ 'status' => TRUE,
+ ])->setComponent($this->fieldStorage->getName(), $display_options)
+ ->save();
+ }
+
+ /**
+ * Tests the field configured for date-only.
+ */
+ public function testDateOnly() {
+ $this->fieldStorage->setSetting('datetime_type', DateRangeItem::DATETIME_TYPE_DATE);
+ $field_name = $this->fieldStorage->getName();
+ // Create an entity.
+ $entity = EntityTest::create([
+ 'name' => $this->randomString(),
+ $field_name => [
+ 'value' => '2016-09-21',
+ 'end_value' => '2016-09-21',
+ ],
+ ]);
+
+ // Dates are saved without a time value. When they are converted back into
+ // a \Drupal\datetime\DateTimeComputed object they should all have the same
+ // time.
+ $start_date = $entity->{$field_name}->start_date;
+ sleep(1);
+ $end_date = $entity->{$field_name}->end_date;
+ $this->assertEquals($start_date->getTimestamp(), $end_date->getTimestamp());
+ }
+
+}