diff --git a/history.md b/history.md index 7ab49baacc..cba6c481af 100644 --- a/history.md +++ b/history.md @@ -51,6 +51,7 @@ Semantic Versioning 2.0.0 is from version 0.1.6+ - [x] (Fixed) _Back-end_ Suggest API gives 200 when no suggestions are found (PR #1797) - [x] (Fixed) _Back-end_ Timeout in Thumbnail cleaner fixed (PR #1798) - [x] (Fixed) _Back-end_ Add logging for thumbnail background scanning (PR #1798) +- [x] (Fixed) _Front-end_ Invalid date parsing (PR #1802, Issue #1508) ## version 0.6.2 - 2024-10-11 {#v0.6.2} diff --git a/starsky/starsky/clientapp/src/shared/data.spec.ts b/starsky/starsky/clientapp/src/shared/data.spec.ts index 5de76fb9cb..9a36cb8a19 100644 --- a/starsky/starsky/clientapp/src/shared/data.spec.ts +++ b/starsky/starsky/clientapp/src/shared/data.spec.ts @@ -24,6 +24,12 @@ describe("date", () => { // NOT Invalid! expect(result).not.toBe("Invalid Date"); }); + + it("Timezone time", () => { + const result = parseDate("2020-04-28T10:44:43.123456+01:00", SupportedLanguages.nl); + expect(result).toBe("dinsdag 28 april 2020"); + }); + it("wrong format", () => { const result = parseDate("2020-30", SupportedLanguages.nl); expect(result).toBe("Invalid Date"); @@ -51,6 +57,11 @@ describe("date", () => { expect(result).toBe("01:01:01"); }); + it("Timezone time (parseTime)", () => { + const result = parseTime("2020-04-28T10:44:43.123456+01:00"); + expect(result).toBe("09:44:43"); + }); + it("right formatted summer time (nl)", () => { const result = parseTime("2020-04-10T23:40:33"); expect(result).toBe("23:40:33"); @@ -73,6 +84,11 @@ describe("date", () => { expect(result).toBe(1); }); + it("Timezone time (parseTimeHour)", () => { + const result = parseTimeHour("2020-04-28T10:44:43.123456+01:00"); + expect(result).toBe(9); + }); + it("right formatted summer time (nl)", () => { const result = parseTimeHour("2020-04-10T23:40:33"); expect(result).toBe(23); @@ -95,6 +111,11 @@ describe("date", () => { expect(result).toBe(1); }); + it("Timezone time (parseDateDate)", () => { + const result = parseDateDate("2020-04-28T10:44:43.123456+01:00"); + expect(result).toBe(28); + }); + it("right formatted summer time (nl)", () => { const result = parseDateDate("2020-04-10T23:40:33"); expect(result).toBe(10); @@ -117,6 +138,11 @@ describe("date", () => { expect(result).toBe(1); }); + it("Timezone time (parseDateMonth)", () => { + const result = parseDateMonth("2020-04-28T10:44:43.123456+01:00"); + expect(result).toBe(4); + }); + it("right formatted summer time (nl)", () => { const result = parseDateMonth("2020-12-10T23:40:33"); expect(result).toBe(12); @@ -139,6 +165,11 @@ describe("date", () => { expect(result).toBe(2020); }); + it("Timezone time (parseDateYear)", () => { + const result = parseDateYear("2020-04-28T10:44:43.123456+01:00"); + expect(result).toBe(2020); + }); + it("right formatted summer time (nl)", () => { const result = parseDateYear("2020-12-10T23:40:33"); expect(result).toBe(2020); @@ -160,6 +191,11 @@ describe("date", () => { const result = isValidDate("2019-10-12 14:12:00"); expect(result).toBeTruthy(); }); + + it("Timezone time (isValidDate)", () => { + const result = isValidDate("2020-04-28T10:44:43.123456+01:00"); + expect(result).toBe(true); + }); }); describe("parseRelativeDate", () => { @@ -178,6 +214,12 @@ describe("date", () => { expect(result).toBe(""); }); + it("Timezone time (isValidDate)", () => { + const result = parseRelativeDate("2020-04-28T10:44:43.123456+01:00", SupportedLanguages.en); + expect(result).toContain("Tuesday"); // with or without comma + expect(result).toContain("28 April 2020"); + }); + it("yesterday", () => { const yesterdayDate = new Date(); diff --git a/starsky/starsky/clientapp/src/shared/date.ts b/starsky/starsky/clientapp/src/shared/date.ts index 1112cfd1a4..caaf546b93 100644 --- a/starsky/starsky/clientapp/src/shared/date.ts +++ b/starsky/starsky/clientapp/src/shared/date.ts @@ -70,15 +70,24 @@ const parseRelativeDate = ( return parseDate(inputDateTime, locate); } }; + +const IsIncludeTimezone = (dateTime: string): boolean => { + const timeZoneRegex = /\+\d{2}:\d{2}/; + return timeZoneRegex.test(dateTime); +}; + /** * Get Date complete parsed for example: Monday, 4 May 2020 - * @param dateTime 2018-09-11T11:23:19 or 2018-09-11T11:23:19Z + * @param dateTime 2018-09-11T11:23:19, 2018-09-11T11:23:19Z or 2020-04-28T10:44:43.123456+01:00 * @param locate Language */ const parseDate = (dateTime: string | undefined, locate: SupportedLanguages): string => { if (!dateTime) return ""; + // UTC DateTime already ends with Z - const dateTimeObject = new Date(!dateTime.endsWith("Z") ? `${dateTime}Z` : dateTime); + const dateTimeObject = new Date( + !dateTime.endsWith("Z") && !IsIncludeTimezone(dateTime) ? `${dateTime}Z` : dateTime + ); // We prefer British English, uses day-month-year order const locateString = locate === SupportedLanguages.en ? "en-GB" : locate.toString(); if (dateTime.endsWith("Z")) { @@ -107,7 +116,9 @@ const parseDateDate = (dateTime: string | undefined): number => { if (!isValidDate(dateTime) || !dateTime) { return 1; } - const dateTimeObject = new Date(!dateTime.endsWith("Z") ? `${dateTime}Z` : dateTime); + const dateTimeObject = new Date( + !dateTime.endsWith("Z") && !IsIncludeTimezone(dateTime) ? `${dateTime}Z` : dateTime + ); // toLocaleDateString assumes that the input is UTC, which is usually not the case const numberValue = dateTimeObject.toLocaleDateString([], { timeZone: !dateTime.endsWith("Z") ? "UTC" : undefined, @@ -124,7 +135,9 @@ const parseDateYear = (dateTime: string | undefined): number => { if (!isValidDate(dateTime) || !dateTime) { return 1; } - const dateTimeObject = new Date(!dateTime.endsWith("Z") ? `${dateTime}Z` : dateTime); + const dateTimeObject = new Date( + !dateTime.endsWith("Z") && !IsIncludeTimezone(dateTime) ? `${dateTime}Z` : dateTime + ); // toLocaleDateString assumes that the input is UTC, which is usually not the case const numberValue = dateTimeObject.toLocaleDateString([], { timeZone: !dateTime.endsWith("Z") ? "UTC" : undefined, @@ -141,7 +154,9 @@ const parseDateMonth = (dateTime: string | undefined): number => { if (!isValidDate(dateTime) || !dateTime) { return 1; } - const dateTimeObject = new Date(!dateTime.endsWith("Z") ? `${dateTime}Z` : dateTime); + const dateTimeObject = new Date( + !dateTime.endsWith("Z") && !IsIncludeTimezone(dateTime) ? `${dateTime}Z` : dateTime + ); // toLocaleDateString assumes that the input is UTC, which is usually not the case const numberValue = dateTimeObject.toLocaleDateString([], { timeZone: !dateTime.endsWith("Z") ? "UTC" : undefined, @@ -158,7 +173,9 @@ const parseTime = (dateTime: string | undefined): string => { if (!isValidDate(dateTime) || !dateTime) { return ""; } - const dateTimeObject = new Date(!dateTime.endsWith("Z") ? `${dateTime}Z` : dateTime); + const dateTimeObject = new Date( + !dateTime.endsWith("Z") && !IsIncludeTimezone(dateTime) ? `${dateTime}Z` : dateTime + ); // toLocaleDateString assumes that the input is UTC, which is usually not the case return dateTimeObject.toLocaleTimeString([], { @@ -178,7 +195,9 @@ const parseTimeHour = (dateTime: string | undefined): number => { if (!isValidDate(dateTime) || !dateTime) { return 1; } - const dateTimeObject = new Date(!dateTime.endsWith("Z") ? `${dateTime}Z` : dateTime); + const dateTimeObject = new Date( + !dateTime.endsWith("Z") && !IsIncludeTimezone(dateTime) ? `${dateTime}Z` : dateTime + ); // toLocaleDateString assumes that the input is UTC, which is usually not the case const numberValue = dateTimeObject.toLocaleTimeString([], { timeZone: !dateTime.endsWith("Z") ? "UTC" : undefined,