Skip to content

Commit

Permalink
fix: parse ISO times taking local time into account
Browse files Browse the repository at this point in the history
Add handling for the different timezones during parsing ISO dates as there's
a difference in date parsing and date-times parsing in the ECMA-script specs.
Fix the bit where even dates with given timezones were parsed as local time.

Related To #9941
  • Loading branch information
felix-gohla committed May 3, 2023
1 parent ce56b2b commit eec1989
Showing 1 changed file with 25 additions and 9 deletions.
34 changes: 25 additions & 9 deletions src/util/DateUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ export class DateUtils {
): Date {
let date =
typeof mixedDate === "string"
? DateUtils.parseDateAsISO(mixedDate)
? DateUtils.parseDateAsISOLocal(mixedDate)
: mixedDate

if (toUtc)
Expand Down Expand Up @@ -268,21 +268,37 @@ export class DateUtils {
}

/**
* Parse a date without the UTC-offset of the device
* Parse a ISO 8601 date(-time) string taking into account the local timezone (if none is given).
*
* The problem here is with wrong timezone.
* The problem here is with wrong timezone and ECMA-Script being weird about when to use time zones and when not.
*
* **Caution:** The function expects an ISO8601 date(-time) string as input.
*
* For example:
*
* ``new Date('2021-04-28')`` will generate `2021-04-28T00:00:00.000Z`
* in my timezone, which is not true for my timezone (GMT-0300). It should
* be `2021-04-28T03:00:00.000Z` as `new Date(2021, 3, 28)` generates.
*/
private static parseDateAsISO(dateString: string): Date {
const date = new Date(dateString)
const offset = date.getTimezoneOffset() * 60 * 1000
const utc = date.getTime() + offset

return new Date(utc)
private static parseDateAsISOLocal(isoDateString: string): Date {
// From ECMA-262 specification:
// "The String may be interpreted as a local time, a UTC time, or a time in some other time zone, depending on the contents of the String. [...]
// When the UTC offset representation is absent, date-only forms are interpreted as a UTC time and date-time forms are interpreted as a local time."
// See https://tc39.es/ecma262/#sec-date-time-string-format for further information

const isDateTime = isoDateString.includes("T")
if (!isDateTime) {
// This lets the date parser now that the date is to be treat as local time.
isoDateString = `${isoDateString}T00:00:00`
}
const parsed = new Date(isoDateString)
console.log(
"isIsoDataTime",
isDateTime,
isoDateString,
parsed,
parsed.toISOString(),
)
return parsed
}
}

0 comments on commit eec1989

Please sign in to comment.