From fba322b5481efcf41ea01e1a07b97459fac0ab71 Mon Sep 17 00:00:00 2001 From: Etheryte Date: Wed, 29 May 2024 20:16:29 +0300 Subject: [PATCH] Test internalized server date time parsing --- .../recurring/recurring-actions-details.tsx | 4 +--- .../src/utils/datetime/localizedMoment.ts | 23 +++++++++++++++---- 2 files changed, 20 insertions(+), 7 deletions(-) diff --git a/web/html/src/manager/recurring/recurring-actions-details.tsx b/web/html/src/manager/recurring/recurring-actions-details.tsx index 8c0fbde11427..7f767f7ff5e6 100644 --- a/web/html/src/manager/recurring/recurring-actions-details.tsx +++ b/web/html/src/manager/recurring/recurring-actions-details.tsx @@ -148,9 +148,7 @@ class RecurringActionsDetails extends React.Component diff --git a/web/html/src/utils/datetime/localizedMoment.ts b/web/html/src/utils/datetime/localizedMoment.ts index f341ab0aaa3a..4f32ffd2749f 100644 --- a/web/html/src/utils/datetime/localizedMoment.ts +++ b/web/html/src/utils/datetime/localizedMoment.ts @@ -44,9 +44,8 @@ declare global { } } -if (process.env.NODE_ENV !== "production") { - (window as any).localizedMoment = localizedMomentConstructor; -} +// This is for debugging purposes only, if you need to use this module, import it properly +(window as any).localizedMoment = localizedMomentConstructor; function validateOrGuessTimeZone(input: string | undefined, errorLabel: "Server" | "User") { try { @@ -139,6 +138,13 @@ declare module "moment" { const userTimeZone: string; /** Abbreviated user time zone string, e.g. `"JST"` */ const userTimeZoneAbbr: string; + + /** + * Parse a date time string provided in the server time zone, e.g. `localizedMoment.fromServerString("May 29, 2024, 11:26:06 AM")`. + * + * @deprecated This function exists for backwards compatibility, for new backend code use ISO 8601 and call `localizedMoment(input)` directly. + */ + const fromServerDateTimeString: (input: string) => moment.Moment; } moment.fn.toServerString = function (this: moment.Moment): string { @@ -197,6 +203,13 @@ Object.defineProperties(moment, { return (userTimeZoneAbbr ??= moment().tz(config.userTimeZone).format("z")); }, }, + fromServerDateTimeString: { + get() { + // TODO: Is this format string correct? Maybe there's a library constant we can use here? + return (input: string): moment.Moment => + moment.tz(input, "MMM DD, YYYY, HH:mm:ss A", true, config.serverTimeZone); + }, + }, }); const parseTimeString = function (input: string): { hours: number; minutes: number } | null { @@ -218,7 +231,9 @@ function localizedMomentConstructor(input?: moment.MomentInput) { : moment(input, true).utc().tz("UTC"); if (!utcMoment.isValid()) { - throw new RangeError("Invalid localized moment on input " + JSON.stringify(input)); + throw new RangeError( + `Invalid input for localized moment, got input with type "${typeof input}" and value ${input}` + ); } return utcMoment;