Skip to content

PlainDate.from('2020-01-01T00:00Z') is problematic #1751

@justingrant

Description

@justingrant

Should PlainDate.from('2020-01-01T00:00Z') throw? This question came up while @ptomato was building #1749, which was based on feedback from IETF that "...Z[IANA]" strings should be valid. This issue poses the reverse question: should "Z" be prohibited for types like PlainDate?

If "Z" means "an unmoored instant that does not represent local time" then throwing in that case might make sense because the Z means that none of the date/time units are meaningful for any Plain type.

A programmer who tries to parse a Z string into a PlainDate is almost certainly committing an error. A typical example is log parsing:

getLogDateForUI(logLine) {
  // Example line: 2021-01-21T23:08:34.456 Database crash
  const timestamp = logLine.split(' ')[0];
  return Temporal.PlainDate.from(timestamp); // BUG! (if this date is assumed to match local date)
  
  // Here's what *should* be used for this case:
  return Temporal.Instant.from(timestamp).toZonedDateTimeISO(myTimeZone).toPlainDate();  
}

Another case where this could bite the developer would be parsing data that was originally in Wall+Offset format, but later changes to Instant+Z format. A naive developer might look at the original data and assume it's safe to parse into a PlainDate, but when the data format changes their app is broken but no error is shown.

Another side effect of the current behavior is that using a Z string for a relativeTo will use the UTC units, which is unlikely to match the developer's intent.

In the unusual case where the developer really wants to measure the date/time units in a Z string, there's an easy opt-in path that expresses a really clear programmer intent for all later readers of the code:

// Use the special time zone "UTC" whose local time matches Z timestamps
Instant.from('2020-01-01T00:00Z').toZonedDateTimeISO('UTC').hour

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions