diff --git a/core/modules/views/src/Plugin/views/filter/Date.php b/core/modules/views/src/Plugin/views/filter/Date.php index 3725281cad2cefb3744962904a3d83b7a83489c6..7597f1873f22316dc18d4c209ead89d03c4029c5 100644 --- a/core/modules/views/src/Plugin/views/filter/Date.php +++ b/core/modules/views/src/Plugin/views/filter/Date.php @@ -184,11 +184,27 @@ protected function opBetween($field) { $a = intval(strtotime($this->value['min'], 0)); $b = intval(strtotime($this->value['max'], 0)); + if ($this->value['type'] == 'date') { + // Check if the max value lacks a time component (i.e., user selected only a date). + if (date('H:i:s', strtotime($this->value['max'])) == '00:00:00') { + $b = intval(strtotime($this->value['max'] . ' +1 day', 0)) - 1; + } + } + if ($this->value['type'] == 'offset') { // Keep sign. $a = '***CURRENT_TIME***' . sprintf('%+d', $a); + // Keep sign for max, store original for checking. + $b_original = $b; // Keep sign. $b = '***CURRENT_TIME***' . sprintf('%+d', $b); + // If min and max are the same and max has no time part (whole days only). + if ($this->value['min'] === $this->value['max'] && ($b_original % 86400 === 0)) { + // Convert offset to days. + $offset_days = intdiv($b_original, 86400); + // Set $b to the end of that day (23:59:59). + $b = '***CURRENT_TIME***' . sprintf('%+d', ($offset_days * 86400) + 86399); + } } // This is safe because we are manually scrubbing the values. It is // necessary to do it this way because $a and $b are formulas when using an diff --git a/core/modules/views/tests/src/Functional/Handler/FilterDateTest.php b/core/modules/views/tests/src/Functional/Handler/FilterDateTest.php index 5cb8d0cd51e33d88be13dc0d0aced07a0de2619b..ec5429d3128ba27037a9d33ed918ea5921d0c8a2 100644 --- a/core/modules/views/tests/src/Functional/Handler/FilterDateTest.php +++ b/core/modules/views/tests/src/Functional/Handler/FilterDateTest.php @@ -134,6 +134,42 @@ protected function _testOffset(): void { ['nid' => $this->nodes[3]->id()], ]; $this->assertIdenticalResultset($view, $expected_result, $this->map); + $view->destroy(); + + // Test offset for between operator with same date offset. + $view->initHandlers(); + $view->filter['created']->operator = 'between'; + $view->filter['created']->value['type'] = 'offset'; + $view->filter['created']->value['max'] = '+1 day'; + $view->filter['created']->value['min'] = '+1 day'; + $view->executeDisplay('default'); + $expected_result = [ + ['nid' => $this->nodes[3]->id()], + ]; + $this->assertIdenticalResultset($view, $expected_result, $this->map); + $view->destroy(); + + // Test offset for between operator with time component. + $view->initHandlers(); + $view->filter['created']->operator = 'between'; + $view->filter['created']->value['type'] = 'offset'; + $view->filter['created']->value['max'] = '+1 day 4 hours'; + $view->filter['created']->value['min'] = '+1 day'; + $view->executeDisplay('default'); + $expected_result = [ + ['nid' => $this->nodes[3]->id()], + ]; + $this->assertIdenticalResultset($view, $expected_result, $this->map); + $view->destroy(); + + // Test offset for between operator with no result. + $view->initHandlers(); + $view->filter['created']->operator = 'between'; + $view->filter['created']->value['type'] = 'offset'; + $view->filter['created']->value['max'] = '+1 day 12 hours'; + $view->filter['created']->value['min'] = '+1 day 6 hours'; + $view->executeDisplay('default'); + $this->assertIdenticalResultset($view, [], $this->map); } /** @@ -166,6 +202,39 @@ protected function _testBetween(): void { $this->assertIdenticalResultset($view, $expected_result, $this->map); $view->destroy(); + // Test between with same min and max date. + $view->initHandlers(); + $view->filter['created']->operator = 'between'; + $view->filter['created']->value['min'] = '1970-01-03'; + $view->filter['created']->value['max'] = '1970-01-03'; + $view->executeDisplay('default'); + $expected_result = [ + ['nid' => $this->nodes[1]->id()], + ]; + $this->assertIdenticalResultset($view, $expected_result, $this->map); + $view->destroy(); + + // Test between with same min and max date with time value. + $view->initHandlers(); + $view->filter['created']->operator = 'between'; + $view->filter['created']->value['min'] = '1970-01-03 12:00:00'; + $view->filter['created']->value['max'] = '1970-01-03 18:00:00'; + $view->executeDisplay('default'); + $expected_result = [ + ['nid' => $this->nodes[1]->id()], + ]; + $this->assertIdenticalResultset($view, $expected_result, $this->map); + $view->destroy(); + + // Test between with same min and max date with no results. + $view->initHandlers(); + $view->filter['created']->operator = 'between'; + $view->filter['created']->value['min'] = '1970-01-03 12:00:00'; + $view->filter['created']->value['max'] = '1970-01-03 16:00:00'; + $view->executeDisplay('default'); + $this->assertIdenticalResultset($view, [], $this->map); + $view->destroy(); + // Test not between with min and max. $view->initHandlers(); $view->filter['created']->operator = 'not between';