diff --git a/packages/main/cypress/specs/DynamicDateRange.cy.tsx b/packages/main/cypress/specs/DynamicDateRange.cy.tsx index 792fe4c5fbf4f..0b97a954dfed6 100644 --- a/packages/main/cypress/specs/DynamicDateRange.cy.tsx +++ b/packages/main/cypress/specs/DynamicDateRange.cy.tsx @@ -3,6 +3,7 @@ import Label from "../../src/Label.js"; import SingleDate from '../../src/dynamic-date-range-options/SingleDate.js'; import DateRange from '../../src/dynamic-date-range-options/DateRange.js'; import Today from '../../src/dynamic-date-range-options/Today.js'; +import { calendarTimestampToLocalDate } from '../../src/dynamic-date-range-options/toDates.js'; import LastOptions from '../../src/dynamic-date-range-options/LastOptions.js'; import NextOptions from '../../src/dynamic-date-range-options/NextOptions.js'; import DateTimeRange from '../../src/dynamic-date-range-options/DateTimeRange.js'; @@ -888,4 +889,17 @@ describe("DynamicDateRange DateTimeRange Option", () => { .should("contain.value", "Mar 5, 2025") .and("contain.value", "Mar 6, 2025"); }); +}); + +describe("calendarTimestampToLocalDate", () => { + it("local date components match the UTC date of the calendar timestamp", () => { + // 1747267200 = 2025-05-15 00:00:00 UTC — same timestamp the calendar fires for May 15 + const ts = 1747267200; + const result = calendarTimestampToLocalDate(ts); + const ref = new Date(ts * 1000); + + expect(result.getFullYear()).to.equal(ref.getUTCFullYear()); + expect(result.getMonth()).to.equal(ref.getUTCMonth()); + expect(result.getDate()).to.equal(ref.getUTCDate()); + }); }); \ No newline at end of file diff --git a/packages/main/src/dynamic-date-range-options/DateRange.ts b/packages/main/src/dynamic-date-range-options/DateRange.ts index 8f9e08a0821cc..3fe3f4293483b 100644 --- a/packages/main/src/dynamic-date-range-options/DateRange.ts +++ b/packages/main/src/dynamic-date-range-options/DateRange.ts @@ -1,12 +1,12 @@ import DateRangeTemplate from "./DateRangeTemplate.js"; import type { DynamicDateRangeValue, IDynamicDateRangeOption } from "../DynamicDateRange.js"; import DateFormat from "@ui5/webcomponents-localization/dist/DateFormat.js"; -import UI5Date from "@ui5/webcomponents-localization/dist/dates/UI5Date.js"; +import type UI5Date from "@ui5/webcomponents-localization/dist/dates/UI5Date.js"; import type { JsxTemplate } from "@ui5/webcomponents-base/dist/index.js"; import { DYNAMIC_DATE_RANGE_DATERANGE_TEXT, } from "../generated/i18n/i18n-defaults.js"; -import { dateRangeOptionToDates } from "./toDates.js"; +import { dateRangeOptionToDates, calendarTimestampToLocalDate } from "./toDates.js"; import DynamicDateRange from "../DynamicDateRange.js"; /** @@ -85,11 +85,11 @@ class DateRange implements IDynamicDateRangeOption { currentValue.operator = this.operator; if (e.detail.selectedDates[0]) { - currentValue.values[0] = UI5Date.getInstance(e.detail.selectedDates[0] * 1000); + currentValue.values[0] = calendarTimestampToLocalDate(e.detail.selectedDates[0] as number); } if (e.detail.selectedDates[1]) { - currentValue.values[1] = UI5Date.getInstance(e.detail.selectedDates[1] * 1000); + currentValue.values[1] = calendarTimestampToLocalDate(e.detail.selectedDates[1] as number); } // Handle backwards date ranges by automatically flipping them diff --git a/packages/main/src/dynamic-date-range-options/FromDateTime.ts b/packages/main/src/dynamic-date-range-options/FromDateTime.ts index b0427266f7b34..1b7adc88fd705 100644 --- a/packages/main/src/dynamic-date-range-options/FromDateTime.ts +++ b/packages/main/src/dynamic-date-range-options/FromDateTime.ts @@ -1,7 +1,6 @@ import FromDateTimeTemplate from "./FromDateTimeTemplate.js"; import type { DynamicDateRangeValue, IDynamicDateRangeOption } from "../DynamicDateRange.js"; import DateFormat from "@ui5/webcomponents-localization/dist/DateFormat.js"; -import UI5Date from "@ui5/webcomponents-localization/dist/dates/UI5Date.js"; import type { JsxTemplate } from "@ui5/webcomponents-base/dist/index.js"; import { DATETIME_PICKER_DATE_BUTTON, @@ -9,7 +8,7 @@ import { DYNAMIC_DATE_RANGE_FROM_INPUT_TEXT, DYNAMIC_DATE_RANGE_FROM_TEXT, } from "../generated/i18n/i18n-defaults.js"; -import { dateTimeOptionToDates } from "./toDates.js"; +import { dateTimeOptionToDates, calendarTimestampToLocalDate } from "./toDates.js"; import DynamicDateRange from "../DynamicDateRange.js"; /** @@ -28,7 +27,7 @@ class FromDateTime implements IDynamicDateRangeOption { constructor() { this.template = FromDateTimeTemplate; this._showTimeView = false; - this._currentDateValue = UI5Date.getInstance(); + this._currentDateValue = new Date(); } parse(value: string): DynamicDateRangeValue { @@ -155,8 +154,8 @@ class FromDateTime implements IDynamicDateRangeOption { if (target.hasAttribute("ui5-calendar")) { if (e.detail.selectedDates[0]) { - const tempDate = UI5Date.getInstance(e.detail.selectedDates[0] * 1000); - this._currentDateValue.setFullYear(tempDate.getFullYear(), tempDate.getMonth(), tempDate.getDate()); + const localDate = calendarTimestampToLocalDate(e.detail.selectedDates[0] as number); + this._currentDateValue.setFullYear(localDate.getFullYear(), localDate.getMonth(), localDate.getDate()); currentValue.values = [this._currentDateValue]; } } diff --git a/packages/main/src/dynamic-date-range-options/SingleDate.ts b/packages/main/src/dynamic-date-range-options/SingleDate.ts index 5e9b634637990..4d71ac954da4a 100644 --- a/packages/main/src/dynamic-date-range-options/SingleDate.ts +++ b/packages/main/src/dynamic-date-range-options/SingleDate.ts @@ -5,7 +5,7 @@ import type { JsxTemplate } from "@ui5/webcomponents-base/dist/index.js"; import { DYNAMIC_DATE_RANGE_DATE_TEXT, } from "../generated/i18n/i18n-defaults.js"; -import { dateOptionToDates } from "./toDates.js"; +import { dateOptionToDates, calendarTimestampToLocalDate } from "./toDates.js"; import DynamicDateRange from "../DynamicDateRange.js"; /** @@ -76,7 +76,7 @@ class SingleDate implements IDynamicDateRangeOption { currentValue.operator = this.operator; if (e.detail.selectedDates[0]) { - currentValue.values[0] = new Date(e.detail.selectedDates[0] * 1000); + currentValue.values[0] = calendarTimestampToLocalDate(e.detail.selectedDates[0] as number); } return currentValue; diff --git a/packages/main/src/dynamic-date-range-options/ToDateTime.ts b/packages/main/src/dynamic-date-range-options/ToDateTime.ts index b2c72f42b0043..c41cf9a09db53 100644 --- a/packages/main/src/dynamic-date-range-options/ToDateTime.ts +++ b/packages/main/src/dynamic-date-range-options/ToDateTime.ts @@ -1,7 +1,6 @@ import FromDateTimeTemplate from "./FromDateTimeTemplate.js"; import type { DynamicDateRangeValue, IDynamicDateRangeOption } from "../DynamicDateRange.js"; import DateFormat from "@ui5/webcomponents-localization/dist/DateFormat.js"; -import UI5Date from "@ui5/webcomponents-localization/dist/dates/UI5Date.js"; import type { JsxTemplate } from "@ui5/webcomponents-base/dist/index.js"; import { DATETIME_PICKER_DATE_BUTTON, @@ -9,7 +8,7 @@ import { DYNAMIC_DATE_RANGE_TO_INPUT_TEXT, DYNAMIC_DATE_RANGE_TO_TEXT, } from "../generated/i18n/i18n-defaults.js"; -import { dateTimeOptionToDates } from "./toDates.js"; +import { dateTimeOptionToDates, calendarTimestampToLocalDate } from "./toDates.js"; import DynamicDateRange from "../DynamicDateRange.js"; /** @@ -28,7 +27,7 @@ class ToDateTime implements IDynamicDateRangeOption { constructor() { this.template = FromDateTimeTemplate; this._showTimeView = false; - this._currentDateValue = UI5Date.getInstance(); + this._currentDateValue = new Date(); } parse(value: string): DynamicDateRangeValue { @@ -156,8 +155,8 @@ class ToDateTime implements IDynamicDateRangeOption { if (target.hasAttribute("ui5-calendar")) { if (e.detail.selectedDates[0]) { - const tempDate = UI5Date.getInstance(e.detail.selectedDates[0] * 1000); - this._currentDateValue.setFullYear(tempDate.getFullYear(), tempDate.getMonth(), tempDate.getDate()); + const localDate = calendarTimestampToLocalDate(e.detail.selectedDates[0] as number); + this._currentDateValue.setFullYear(localDate.getFullYear(), localDate.getMonth(), localDate.getDate()); currentValue.values = [this._currentDateValue]; } } diff --git a/packages/main/src/dynamic-date-range-options/toDates.ts b/packages/main/src/dynamic-date-range-options/toDates.ts index cfda66bf9e3c1..ea1f8bb304982 100644 --- a/packages/main/src/dynamic-date-range-options/toDates.ts +++ b/packages/main/src/dynamic-date-range-options/toDates.ts @@ -1,5 +1,10 @@ import type { DynamicDateRangeValue, IDynamicDateRangeOption } from "../DynamicDateRange.js"; import UI5Date from "@ui5/webcomponents-localization/dist/dates/UI5Date.js"; +import CalendarDate from "@ui5/webcomponents-localization/dist/dates/CalendarDate.js"; + +const calendarTimestampToLocalDate = (timestampSeconds: number): Date => { + return CalendarDate.fromTimestamp(timestampSeconds * 1000).toLocalJSDate(); +}; const dateOptionToDates = (value: DynamicDateRangeValue): Array => { if (!value || !value.values || value.values.length !== 1) { @@ -211,6 +216,7 @@ const dateTimeOptionToDates = (value: DynamicDateRangeValue): Array => { }; export { + calendarTimestampToLocalDate, dateOptionToDates, dateRangeOptionToDates, dateTimeRangeOptionToDates,