diff --git a/package.json b/package.json index 17af12f076..65011e939a 100644 --- a/package.json +++ b/package.json @@ -47,6 +47,7 @@ "@fullcalendar/daygrid": "6.1.8", "@fullcalendar/interaction": "6.1.8", "@fullcalendar/list": "6.1.8", + "@fullcalendar/luxon3": "6.1.8", "@fullcalendar/timegrid": "6.1.8", "@lezer/highlight": "1.1.6", "@lit-labs/context": "0.3.3", @@ -120,6 +121,7 @@ "leaflet": "1.9.4", "leaflet-draw": "1.0.4", "lit": "2.7.5", + "luxon": "3.3.0", "marked": "4.3.0", "memoize-one": "6.0.0", "node-vibrant": "3.2.1-alpha.1", @@ -174,6 +176,7 @@ "@types/js-yaml": "4.0.5", "@types/leaflet": "1.9.3", "@types/leaflet-draw": "1.0.7", + "@types/luxon": "^3", "@types/marked": "4.3.1", "@types/mocha": "10.0.1", "@types/qrcode": "1.5.1", diff --git a/src/panels/calendar/dialog-calendar-event-editor.ts b/src/panels/calendar/dialog-calendar-event-editor.ts index 0383791284..fcc624b653 100644 --- a/src/panels/calendar/dialog-calendar-event-editor.ts +++ b/src/panels/calendar/dialog-calendar-event-editor.ts @@ -34,6 +34,7 @@ import "../lovelace/components/hui-generic-entity-row"; import "./ha-recurrence-rule-editor"; import { showConfirmEventDialog } from "./show-confirm-event-dialog-box"; import { CalendarEventEditDialogParams } from "./show-dialog-calendar-event-editor"; +import { TimeZone } from "../../data/translation"; const CALENDAR_DOMAINS = ["calendar"]; @@ -81,8 +82,9 @@ class DialogCalendarEventEditor extends LitElement { supportsFeature(stateObj, CalendarEntityFeature.CREATE_EVENT) )?.entity_id; this._timeZone = - Intl.DateTimeFormat().resolvedOptions().timeZone || - this.hass.config.time_zone; + this.hass.locale.time_zone === TimeZone.local + ? Intl.DateTimeFormat().resolvedOptions().timeZone + : this.hass.config.time_zone; if (params.entry) { const entry = params.entry!; this._allDay = isDate(entry.dtstart); diff --git a/src/panels/calendar/ha-full-calendar.ts b/src/panels/calendar/ha-full-calendar.ts index 447d2211f8..897d16f976 100644 --- a/src/panels/calendar/ha-full-calendar.ts +++ b/src/panels/calendar/ha-full-calendar.ts @@ -46,6 +46,7 @@ import type { } from "../../types"; import { showCalendarEventDetailDialog } from "./show-dialog-calendar-event-detail"; import { showCalendarEventEditDialog } from "./show-dialog-calendar-event-editor"; +import { TimeZone } from "../../data/translation"; declare global { interface HTMLElementTagNameMap { @@ -240,9 +241,26 @@ export class HAFullCalendar extends LitElement { } protected firstUpdated(): void { + this._loadCalendar(); + } + + private async _loadCalendar() { + const luxonPlugin = + this.hass.locale.time_zone === TimeZone.local + ? undefined + : (await import("@fullcalendar/luxon3")).default; + const config: CalendarOptions = { ...defaultFullCalendarConfig, + plugins: + this.hass.locale.time_zone === TimeZone.local + ? defaultFullCalendarConfig.plugins + : [...defaultFullCalendarConfig.plugins!, luxonPlugin!], locale: this.hass.language, + timeZone: + this.hass.locale.time_zone === TimeZone.local + ? "local" + : this.hass.config.time_zone, firstDay: firstWeekdayIndex(this.hass.locale), initialView: this.initialView, eventDisplay: this.eventDisplay, diff --git a/src/panels/config/helpers/forms/ha-schedule-form.ts b/src/panels/config/helpers/forms/ha-schedule-form.ts index dbb0b92596..1656fafb00 100644 --- a/src/panels/config/helpers/forms/ha-schedule-form.ts +++ b/src/panels/config/helpers/forms/ha-schedule-form.ts @@ -23,6 +23,7 @@ import { Schedule, ScheduleDay, weekdays } from "../../../../data/schedule"; import { haStyle } from "../../../../resources/styles"; import { HomeAssistant } from "../../../../types"; import { loadPolyfillIfNeeded } from "../../../../resources/resize-observer.polyfill"; +import { TimeZone } from "../../../../data/translation"; import { showConfirmationDialog } from "../../../../dialogs/generic/show-dialog-box"; const defaultFullCalendarConfig: CalendarOptions = { @@ -287,9 +288,18 @@ class HaScheduleForm extends LitElement { const value = [...this[`_${day}`]]; const newValue = { ...this._item }; - const endFormatted = formatTime24h(end, this.hass.locale, this.hass.config); + // Schedule is timezone unaware, we need to format it in local time + const endFormatted = formatTime24h( + end, + { ...this.hass.locale, time_zone: TimeZone.local }, + this.hass.config + ); value.push({ - from: formatTime24h(start, this.hass.locale, this.hass.config), + from: formatTime24h( + start, + { ...this.hass.locale, time_zone: TimeZone.local }, + this.hass.config + ), to: !isSameDay(start, end) || endFormatted === "0:00" ? "24:00" diff --git a/yarn.lock b/yarn.lock index 5e4d79b470..26cb90a3f3 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1777,6 +1777,16 @@ __metadata: languageName: node linkType: hard +"@fullcalendar/luxon3@npm:6.1.8": + version: 6.1.8 + resolution: "@fullcalendar/luxon3@npm:6.1.8" + peerDependencies: + "@fullcalendar/core": ~6.1.8 + luxon: ^3.0.0 + checksum: 7e842006418dc1855efc96fce22c7180f695b2f0087ec6305b62350d74e1776c1f03337f0d8adff7e1387e82535b42ff3481ad25fdbe82b3a5ad0501a902a386 + languageName: node + linkType: hard + "@fullcalendar/timegrid@npm:6.1.8": version: 6.1.8 resolution: "@fullcalendar/timegrid@npm:6.1.8" @@ -4443,6 +4453,13 @@ __metadata: languageName: node linkType: hard +"@types/luxon@npm:^3": + version: 3.3.0 + resolution: "@types/luxon@npm:3.3.0" + checksum: f7e3a89fc3ca404fbc3ea538653ed6860bc28f570a8c4d6d24449b89b9b553b7d6ad6cc94a9e129c5b8c9a2b97f0c365b3017f811e59c4a859a9c219a1c918e0 + languageName: node + linkType: hard + "@types/marked@npm:4.3.1": version: 4.3.1 resolution: "@types/marked@npm:4.3.1" @@ -9623,6 +9640,7 @@ __metadata: "@fullcalendar/daygrid": 6.1.8 "@fullcalendar/interaction": 6.1.8 "@fullcalendar/list": 6.1.8 + "@fullcalendar/luxon3": 6.1.8 "@fullcalendar/timegrid": 6.1.8 "@koa/cors": 4.0.0 "@lezer/highlight": 1.1.6 @@ -9688,6 +9706,7 @@ __metadata: "@types/js-yaml": 4.0.5 "@types/leaflet": 1.9.3 "@types/leaflet-draw": 1.0.7 + "@types/luxon": ^3 "@types/marked": 4.3.1 "@types/mocha": 10.0.1 "@types/qrcode": 1.5.1 @@ -9758,6 +9777,7 @@ __metadata: lit: 2.7.5 lit-analyzer: 2.0.0-pre.3 lodash.template: 4.5.0 + luxon: 3.3.0 magic-string: 0.30.0 map-stream: 0.0.7 marked: 4.3.0 @@ -11636,6 +11656,13 @@ __metadata: languageName: node linkType: hard +"luxon@npm:3.3.0": + version: 3.3.0 + resolution: "luxon@npm:3.3.0" + checksum: 50cf17a0dc155c3dcacbeae8c0b7e80db425e0ba97b9cbdf12a7fc142d841ff1ab1560919f033af46240ed44e2f70c49f76e3422524c7fc8bb8d81ca47c66187 + languageName: node + linkType: hard + "magic-string@npm:0.30.0": version: 0.30.0 resolution: "magic-string@npm:0.30.0"