diff --git a/core/modules/datetime/src/Plugin/views/filter/Date.php b/core/modules/datetime/src/Plugin/views/filter/Date.php index cc67288..6fe2c30 100644 --- a/core/modules/datetime/src/Plugin/views/filter/Date.php +++ b/core/modules/datetime/src/Plugin/views/filter/Date.php @@ -77,9 +77,10 @@ protected function opBetween($field) { $a = intval(strtotime($this->value['min'], $origin)); $b = intval(strtotime($this->value['max'], $origin)); - // Convert to ISO format and format for query. - $a = $this->query->getDateFormat("'" . $this->dateFormatter->format($a, 'custom', 'c') . "'", static::$dateFormat, TRUE); - $b = $this->query->getDateFormat("'" . $this->dateFormatter->format($b, 'custom', 'c') . "'", static::$dateFormat, TRUE); + // Convert to ISO format and format for query. UTC timezone is used since + // dates are stored in UTC. + $a = $this->query->getDateFormat("'" . $this->dateFormatter->format($a, 'custom', DATETIME_DATETIME_STORAGE_FORMAT, DATETIME_STORAGE_TIMEZONE) . "'", static::$dateFormat, TRUE); + $b = $this->query->getDateFormat("'" . $this->dateFormatter->format($b, 'custom', DATETIME_DATETIME_STORAGE_FORMAT, DATETIME_STORAGE_TIMEZONE) . "'", static::$dateFormat, TRUE); // This is safe because we are manually scrubbing the values. $operator = strtoupper($this->operator); @@ -94,8 +95,8 @@ protected function opSimple($field) { $origin = (!empty($this->value['type']) && $this->value['type'] == 'offset') ? REQUEST_TIME : 0; $value = intval(strtotime($this->value['value'], $origin)); - // Convert to ISO. - $value = $this->query->getDateFormat("'" . $this->dateFormatter->format($value, 'custom', 'c') . "'", static::$dateFormat, TRUE); + // Convert to ISO. UTC is used since dates are stored in UTC. + $value = $this->query->getDateFormat("'" . $this->dateFormatter->format($value, 'custom', DATETIME_DATETIME_STORAGE_FORMAT, DATETIME_STORAGE_TIMEZONE) . "'", static::$dateFormat, TRUE); // This is safe because we are manually scrubbing the value. $field = $this->query->getDateFormat($field, static::$dateFormat, TRUE); diff --git a/core/modules/datetime/src/Tests/Views/DateTimeHandlerTestBase.php b/core/modules/datetime/src/Tests/Views/DateTimeHandlerTestBase.php index 7eec9e6..4678be9 100644 --- a/core/modules/datetime/src/Tests/Views/DateTimeHandlerTestBase.php +++ b/core/modules/datetime/src/Tests/Views/DateTimeHandlerTestBase.php @@ -33,7 +33,7 @@ /** * Nodes to test. * - * @var array + * @var \Drupal\node\NodeInterface[] */ protected $nodes = array(); diff --git a/core/modules/datetime/src/Tests/Views/FilterDateTimeTest.php b/core/modules/datetime/src/Tests/Views/FilterDateTimeTest.php index 34e7019..5eac489 100644 --- a/core/modules/datetime/src/Tests/Views/FilterDateTimeTest.php +++ b/core/modules/datetime/src/Tests/Views/FilterDateTimeTest.php @@ -7,6 +7,7 @@ namespace Drupal\datetime\Tests\Views; +use Drupal\Core\Datetime\Element\Datetime; use Drupal\views\Views; /** @@ -22,19 +23,26 @@ class FilterDateTimeTest extends DateTimeHandlerTestBase { public static $testViews = array('test_filter_datetime'); /** + * For offset tests, set a date 1 day in the future. + */ + protected static $date; + + /** * {@inheritdoc} */ public function setUp() { parent::setUp(); + static::$date = REQUEST_TIME + 86400; + // Add some basic test nodes. $dates = array( '2000-10-10', '2001-10-10', '2002-10-10', - // For the offset test, put a date 24 hours in the future. The `time()` - // function is used in case REQUEST_TIME is stale from long-running tests. - \Drupal::service('date.formatter')->format(REQUEST_TIME + 86400, 'custom', DATETIME_DATETIME_STORAGE_FORMAT), + // The date storage timezone is used (this mimics the steps taken in the + // widget: \Drupal\datetime\Plugin\Field\FieldWidget::messageFormValues(). + \Drupal::service('date.formatter')->format(static::$date, 'custom', DATETIME_DATETIME_STORAGE_FORMAT, DATETIME_STORAGE_TIMEZONE), ); foreach ($dates as $date) { $this->nodes[] = $this->drupalCreateNode(array( @@ -51,6 +59,7 @@ public function setUp() { public function testDatetimeFilter() { $this->_testOffset(); $this->_testBetween(); + $this->_testExact(); } /** @@ -150,4 +159,29 @@ protected function _testBetween() { $this->assertIdenticalResultset($view, $expected_result, $this->map); } + /** + * Test exact date matching. + */ + protected function _testExact() { + $view = Views::getView('test_filter_datetime'); + $field = static::$field_name . '_value'; + + // Test between with min and max. + $view->initHandlers(); + $view->filter[$field]->operator = '='; + $view->filter[$field]->value['min'] = ''; + $view->filter[$field]->value['max'] = ''; + // Use the date from node 3. Use the site timezone (mimics a value entered + // through the UI). + $view->filter[$field]->value['value'] = \Drupal::service('date.formatter')->format(static::$date, 'custom', DATETIME_DATETIME_STORAGE_FORMAT); + $view->setDisplay('default'); + $this->executeView($view); + $expected_result = array( + array('nid' => $this->nodes[3]->id()), + ); + $this->assertIdenticalResultset($view, $expected_result, $this->map); + $view->destroy(); + + } + }