From 97dfccf4c7d543a590328addad0793ec14c31789 Mon Sep 17 00:00:00 2001 From: Bram Kragten Date: Sat, 1 Feb 2025 17:32:07 +0100 Subject: [PATCH] Make date period picker respect timezone settings (#23996) --- src/components/ha-date-range-picker.ts | 46 +++++++++++++++++-- src/panels/history/ha-panel-history.ts | 6 +-- src/panels/logbook/ha-panel-logbook.ts | 6 +-- .../components/hui-energy-period-selector.ts | 6 +-- 4 files changed, 50 insertions(+), 14 deletions(-) diff --git a/src/components/ha-date-range-picker.ts b/src/components/ha-date-range-picker.ts index 71273a66efce..7dfd0c738362 100644 --- a/src/components/ha-date-range-picker.ts +++ b/src/components/ha-date-range-picker.ts @@ -9,12 +9,13 @@ import { endOfMonth, endOfWeek, endOfYear, + isThisYear, startOfDay, startOfMonth, startOfWeek, startOfYear, - isThisYear, } from "date-fns"; +import { fromZonedTime, toZonedTime } from "date-fns-tz"; import type { PropertyValues, TemplateResult } from "lit"; import { LitElement, css, html, nothing } from "lit"; import { customElement, property, state } from "lit/decorators"; @@ -22,16 +23,18 @@ import { ifDefined } from "lit/directives/if-defined"; import { calcDate, shiftDateRange } from "../common/datetime/calc_date"; import { firstWeekdayIndex } from "../common/datetime/first_weekday"; import { - formatShortDateTimeWithYear, formatShortDateTime, + formatShortDateTimeWithYear, } from "../common/datetime/format_date_time"; import { useAmPm } from "../common/datetime/use_am_pm"; +import { fireEvent } from "../common/dom/fire_event"; +import { TimeZone } from "../data/translation"; import type { HomeAssistant } from "../types"; import "./date-range-picker"; import "./ha-icon-button"; -import "./ha-textarea"; import "./ha-icon-button-next"; import "./ha-icon-button-prev"; +import "./ha-textarea"; export type DateRangePickerRanges = Record; @@ -197,14 +200,15 @@ export class HaDateRangePicker extends LitElement { ?auto-apply=${this.autoApply} time-picker=${this.timePicker} twentyfour-hours=${this._hour24format} - start-date=${this.startDate.toISOString()} - end-date=${this.endDate.toISOString()} + start-date=${this._formatDate(this.startDate)} + end-date=${this._formatDate(this.endDate)} ?ranges=${this.ranges !== false} opening-direction=${ifDefined( this.openingDirection || this._calcedOpeningDirection )} first-day=${firstWeekdayIndex(this.hass.locale)} language=${this.hass.locale.language} + @change=${this._handleChange} >
${!this.minimal @@ -325,9 +329,31 @@ export class HaDateRangePicker extends LitElement { } private _applyDateRange() { + if (this.hass.locale.time_zone === TimeZone.server) { + const dateRangePicker = this._dateRangePicker; + + const startDate = fromZonedTime( + dateRangePicker.start, + this.hass.config.time_zone + ); + const endDate = fromZonedTime( + dateRangePicker.end, + this.hass.config.time_zone + ); + + dateRangePicker.clickRange([startDate, endDate]); + } + this._dateRangePicker.clickedApply(); } + private _formatDate(date: Date): string { + if (this.hass.locale.time_zone === TimeZone.server) { + return toZonedTime(date, this.hass.config.time_zone).toISOString(); + } + return date.toISOString(); + } + private get _dateRangePicker() { const dateRangePicker = this.shadowRoot!.querySelector( "date-range-picker" @@ -358,6 +384,16 @@ export class HaDateRangePicker extends LitElement { } } + private _handleChange(ev: CustomEvent) { + ev.stopPropagation(); + const startDate = ev.detail.startDate; + const endDate = ev.detail.endDate; + + fireEvent(this, "value-changed", { + value: { startDate, endDate }, + }); + } + static styles = css` ha-icon-button { diff --git a/src/panels/history/ha-panel-history.ts b/src/panels/history/ha-panel-history.ts index 977134745d2c..c535c4ac8b5f 100644 --- a/src/panels/history/ha-panel-history.ts +++ b/src/panels/history/ha-panel-history.ts @@ -173,7 +173,7 @@ class HaPanelHistory extends LitElement { .endDate=${this._endDate} extended-presets time-picker - @change=${this._dateRangeChanged} + @value-changed=${this._dateRangeChanged} > @@ -233,8 +233,8 @@ export class HaPanelLogbook extends LitElement { } private _dateRangeChanged(ev) { - const startDate = ev.detail.startDate; - const endDate = ev.detail.endDate; + const startDate = ev.detail.value.startDate; + const endDate = ev.detail.value.endDate; if (endDate.getHours() === 0 && endDate.getMinutes() === 0) { endDate.setDate(endDate.getDate() + 1); endDate.setMilliseconds(endDate.getMilliseconds() - 1); diff --git a/src/panels/lovelace/components/hui-energy-period-selector.ts b/src/panels/lovelace/components/hui-energy-period-selector.ts index a32164ef5ea6..86add3acdd4f 100644 --- a/src/panels/lovelace/components/hui-energy-period-selector.ts +++ b/src/panels/lovelace/components/hui-energy-period-selector.ts @@ -246,7 +246,7 @@ export class HuiEnergyPeriodSelector extends SubscribeMixin(LitElement) { .startDate=${this._startDate} .endDate=${this._endDate || new Date()} .ranges=${this._ranges} - @change=${this._dateRangeChanged} + @value-changed=${this._dateRangeChanged} minimal >
@@ -346,7 +346,7 @@ export class HuiEnergyPeriodSelector extends SubscribeMixin(LitElement) { private _dateRangeChanged(ev) { const weekStartsOn = firstWeekdayIndex(this.hass.locale); this._startDate = calcDate( - ev.detail.startDate, + ev.detail.value.startDate, startOfDay, this.hass.locale, this.hass.config, @@ -355,7 +355,7 @@ export class HuiEnergyPeriodSelector extends SubscribeMixin(LitElement) { } ); this._endDate = calcDate( - ev.detail.endDate, + ev.detail.value.endDate, endOfDay, this.hass.locale, this.hass.config,