From 42370c59387ee88d340db9462a513c8c0ef2839e Mon Sep 17 00:00:00 2001 From: Matt Wistrand Date: Wed, 15 Mar 2017 09:30:26 -0500 Subject: [PATCH] Fix date parsing for DST dates (#67) * Implement a workaround for a Globalize.js bug (https://github.com/globalizejs/globalize/issues/689) that incorrectly parses date strings when the resulting date follows a different rule from today's date (e.g., the parsed date is in standard time while today's date is in daylight savings time). * Temporarily pin Globalize.js version to prevent the `fixParsedDate` method from breaking on the next release of Globalize.js. --- package.json | 2 +- src/date.ts | 31 +++++++++++++++++++++++++++++-- 2 files changed, 30 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index 456ef1d..1af23ab 100644 --- a/package.json +++ b/package.json @@ -23,7 +23,7 @@ "@dojo/shim": "2.0.0-beta.10" }, "dependencies": { - "globalize": "~1.2.2" + "globalize": "1.2.2" }, "devDependencies": { "@dojo/interfaces": "2.0.0-alpha.11", diff --git a/src/date.ts b/src/date.ts index 7b90dd9..dd4b6c2 100644 --- a/src/date.ts +++ b/src/date.ts @@ -52,6 +52,27 @@ export type RelativeTimeFormatterOptions = { form?: RelativeTimeLength; } +// Globalize.js incorrectly handles timezone offsets when parsing date strings. +// This is resolved with https://github.com/globalizejs/globalize/pull/693, and +// will be included with the next release. Until then, the following workaround +// is needed. +const TODAY_OFFSET = new Date().getTimezoneOffset(); +function fixParsedDate(date: Date, optionsOrLocale?: DateFormatterOptions | string): Date { + if (!date || !optionsOrLocale || typeof optionsOrLocale === 'string') { + return date; + } + + const offset = date.getTimezoneOffset(); + const { datetime } = optionsOrLocale; + + if (offset === TODAY_OFFSET || (datetime !== 'long' && datetime !== 'full')) { + return date; + } + + date.setMinutes(date.getMinutes() - (offset - TODAY_OFFSET)); + return date; +} + /** * Format a date according to the specified options for the specified or current locale. * @@ -142,10 +163,14 @@ export function getDateFormatter(optionsOrLocale?: DateFormatterOptions | string export function getDateParser(options?: DateFormatterOptions, locale?: string): DateParser; export function getDateParser(locale?: string): DateParser; export function getDateParser(optionsOrLocale?: DateFormatterOptions | string, locale?: string): DateParser { - return globalizeDelegator('dateParser', { + const parser = globalizeDelegator('dateParser', { locale, optionsOrLocale }); + + return function (dateString: string): Date { + return fixParsedDate(parser(dateString), optionsOrLocale); + }; } /** @@ -193,9 +218,11 @@ export function getRelativeTimeFormatter(unit: string, optionsOrLocale?: Relativ export function parseDate(value: string, options?: DateFormatterOptions, locale?: string): Date; export function parseDate(value: string, locale?: string): Date; export function parseDate(value: string, optionsOrLocale?: DateFormatterOptions | string, locale?: string): Date { - return globalizeDelegator('parseDate', { + const date = globalizeDelegator('parseDate', { locale, optionsOrLocale, value }); + + return fixParsedDate(date, optionsOrLocale); }