From b6cd38ff055f003f92fff4c3e27d165fb4437057 Mon Sep 17 00:00:00 2001 From: Pete Bacon Darwin Date: Thu, 28 Jan 2021 20:49:07 +0000 Subject: [PATCH] fix(common): parse `YYYY-MM` strings as UTC dates (#40620) In 2aba8b0 we fixed the DatePipe so that when it parsed date strings that looked like `YYYY-MM-DD` it created a UTC date that was not affected by the local timezone of the JavaScript engine. This commit does the same for date strings of the form `YYYY-MM` and `YYYY`. Fixes #33944 PR Close #40620 --- packages/common/src/i18n/format_date.ts | 4 ++-- packages/common/test/i18n/format_date_spec.ts | 12 ++++++++++++ 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/packages/common/src/i18n/format_date.ts b/packages/common/src/i18n/format_date.ts index 917f2f0171..acb24f99ca 100644 --- a/packages/common/src/i18n/format_date.ts +++ b/packages/common/src/i18n/format_date.ts @@ -718,7 +718,7 @@ export function toDate(value: string|number|Date): Date { return new Date(parsedNb); } - if (/^(\d{4}-\d{1,2}-\d{1,2})$/.test(value)) { + if (/^(\d{4}(-\d{1,2}(-\d{1,2})?)?)$/.test(value)) { /* For ISO Strings without time the day, month and year must be extracted from the ISO String before Date creation to avoid time offset and errors in the new Date. If we only replace '-' with ',' in the ISO String ("2015,01,01"), and try to create a new @@ -726,7 +726,7 @@ export function toDate(value: string|number|Date): Date { If we leave the '-' ("2015-01-01") and try to create a new Date("2015-01-01") the timeoffset is applied. Note: ISO months are 0 for January, 1 for February, ... */ - const [y, m, d] = value.split('-').map((val: string) => +val); + const [y, m = 1, d = 1] = value.split('-').map((val: string) => +val); return new Date(y, m - 1, d); } diff --git a/packages/common/test/i18n/format_date_spec.ts b/packages/common/test/i18n/format_date_spec.ts index 5931f7222f..fe4dbb83b6 100644 --- a/packages/common/test/i18n/format_date_spec.ts +++ b/packages/common/test/i18n/format_date_spec.ts @@ -60,6 +60,8 @@ describe('Format date', () => { describe('formatDate', () => { const isoStringWithoutTime = '2015-01-01'; + const isoStringWithoutTimeOrDate = '2015-01'; + const isoStringWithoutTimeOrDateOrMonth = '2015-01'; const defaultFormat = 'mediumDate'; let date: Date; @@ -231,6 +233,16 @@ describe('Format date', () => { expectDateFormatAs(isoStringWithoutTime, pattern, isoStringWithoutTimeFixtures[pattern]); }); + Object.keys(isoStringWithoutTimeFixtures).forEach((pattern: string) => { + expectDateFormatAs( + isoStringWithoutTimeOrDate, pattern, isoStringWithoutTimeFixtures[pattern]); + }); + + Object.keys(isoStringWithoutTimeFixtures).forEach((pattern: string) => { + expectDateFormatAs( + isoStringWithoutTimeOrDateOrMonth, pattern, isoStringWithoutTimeFixtures[pattern]); + }); + const nightTime = new Date(2015, 5, 15, 2, 3, 1, 550); Object.keys(midnightCrossingPeriods).forEach(pattern => { expectDateFormatAs(nightTime, pattern, midnightCrossingPeriods[pattern]);