diff --git a/core/modules/datetime/src/Plugin/views/filter/Date.php b/core/modules/datetime/src/Plugin/views/filter/Date.php index 245ca67..1458473 100644 --- a/core/modules/datetime/src/Plugin/views/filter/Date.php +++ b/core/modules/datetime/src/Plugin/views/filter/Date.php @@ -102,27 +102,18 @@ public static function create(ContainerInterface $container, array $configuratio * Override parent method, which deals with dates as integers. */ protected function opBetween($field) { - $timezone = ($this->dateFormat === DateTimeItemInterface::DATE_STORAGE_FORMAT) - ? DateTimeItemInterface::STORAGE_TIMEZONE - : drupal_get_user_timezone(); + $timezone = $this->getTimezone(); + $origin_offset = $this->getOffset($this->value['min'], $timezone); // Although both 'min' and 'max' values are required, default empty 'min' // value as UNIX timestamp 0. $min = (!empty($this->value['min'])) ? $this->value['min'] : '@0'; - $a = new DateTimePlus($min, new \DateTimeZone($timezone)); - $b = new DateTimePlus($this->value['max'], new \DateTimeZone($timezone)); - - // For 'date' types with offset, user's 'now' could not be UTC 'now'. So - // calculate the difference between user's timezone and UTC. - $origin_offset = 0; - if ($this->dateFormat === DateTimeItemInterface::DATE_STORAGE_FORMAT && $this->value['type'] === 'offset') { - $origin_offset = $origin_offset + timezone_offset_get(new \DateTimeZone(drupal_get_user_timezone()), new \DateTime($this->value['min'], new \DateTimeZone($timezone))); - } - // Convert to ISO format and format for query. UTC timezone is used since // dates are stored in UTC. + $a = new DateTimePlus($min, new \DateTimeZone($timezone)); $a = $this->query->getDateFormat($this->query->getDateField("'" . $this->dateFormatter->format($a->getTimestamp() + $origin_offset, 'custom', DateTimeItemInterface::DATETIME_STORAGE_FORMAT, DateTimeItemInterface::STORAGE_TIMEZONE) . "'", TRUE, $this->calculateOffset), $this->dateFormat, TRUE); + $b = new DateTimePlus($this->value['max'], new \DateTimeZone($timezone)); $b = $this->query->getDateFormat($this->query->getDateField("'" . $this->dateFormatter->format($b->getTimestamp() + $origin_offset, 'custom', DateTimeItemInterface::DATETIME_STORAGE_FORMAT, DateTimeItemInterface::STORAGE_TIMEZONE) . "'", TRUE, $this->calculateOffset), $this->dateFormat, TRUE); // This is safe because we are manually scrubbing the values. @@ -135,20 +126,11 @@ protected function opBetween($field) { * Override parent method, which deals with dates as integers. */ protected function opSimple($field) { - $timezone = ($this->dateFormat === DateTimeItemInterface::DATE_STORAGE_FORMAT) - ? DateTimeItemInterface::STORAGE_TIMEZONE - : drupal_get_user_timezone(); - - $value = new DateTimePlus($this->value['value'], new \DateTimeZone($timezone)); - - // For 'date' types with offset, user's 'now' could not be UTC 'now'. So - // calculate the difference between user's timezone and UTC. - $origin_offset = 0; - if ($this->dateFormat === DateTimeItemInterface::DATE_STORAGE_FORMAT && $this->value['type'] === 'offset') { - $origin_offset = $origin_offset + timezone_offset_get(new \DateTimeZone(drupal_get_user_timezone()), new \DateTime($this->value['value'], new \DateTimeZone($timezone))); - } + $timezone = $this->getTimezone(); + $origin_offset = $this->getOffset($this->value['value'], $timezone); // Convert to ISO. UTC timezone is used since dates are stored in UTC. + $value = new DateTimePlus($this->value['value'], new \DateTimeZone($timezone)); $value = $this->query->getDateFormat($this->query->getDateField("'" . $this->dateFormatter->format($value->getTimestamp() + $origin_offset, 'custom', DateTimeItemInterface::DATETIME_STORAGE_FORMAT, DateTimeItemInterface::STORAGE_TIMEZONE) . "'", TRUE, $this->calculateOffset), $this->dateFormat, TRUE); // This is safe because we are manually scrubbing the value. @@ -156,4 +138,46 @@ protected function opSimple($field) { $this->query->addWhereExpression($this->options['group'], "$field $this->operator $value"); } + /** + * Get the proper time zone to use in computations. + * + * Date-only fields do not have a time zone associated with them, so the + * filter input needs to use UTC for reference. Otherwise, use the time zone + * for the current user. + * + * @return string + * The time zone name. + */ + protected function getTimezone() { + return $this->dateFormat === DateTimeItemInterface::DATE_STORAGE_FORMAT + ? DateTimeItemInterface::STORAGE_TIMEZONE + : drupal_get_user_timezone(); + } + + /** + * Get the proper offset from UTC to use in computations. + * + * @param string $time + * A date/time string compatible with \DateTime. It is used as the + * reference for computing the offset, which can vary based on the time + * zone rules. + * + * @param string $timezone + * The time zone that $time is in. + * + * @return int + * The computed offset. + */ + protected function getOffset($time, $timezone) { + // Date-only fields do not have a time zone or offset from UTC associated + // with them. For relative (i.e. 'offset') comparisons, we need to compute + // the user's offset from UTC for use in the query. + $origin_offset = 0; + if ($this->dateFormat === DateTimeItemInterface::DATE_STORAGE_FORMAT && $this->value['type'] === 'offset') { + $origin_offset = $origin_offset + timezone_offset_get(new \DateTimeZone(drupal_get_user_timezone()), new \DateTime($time, new \DateTimeZone($timezone))); + } + + return $origin_offset; + } + } diff --git a/core/modules/views/views.post_update.php b/core/modules/views/views.post_update.php index a4df64f..c41ae7f 100644 --- a/core/modules/views/views.post_update.php +++ b/core/modules/views/views.post_update.php @@ -270,10 +270,3 @@ function views_post_update_bulk_field_moved() { } }); } - -/** - * Rebuild the container to add a new container parameter. - */ -function views_post_update_date_sql_service() { - // Empty update to cause a cache rebuild so that the container is rebuilt. -}