Skip to content

Instantly share code, notes, and snippets.

@bmaupin
Last active November 24, 2021 15:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bmaupin/74a41a98a33c207d47cbb0db5705cd5e to your computer and use it in GitHub Desktop.
Save bmaupin/74a41a98a33c207d47cbb0db5705cd5e to your computer and use it in GitHub Desktop.
JavaScript date/time gotchas

TL;DR

  • The general consensus seems to be use UTC everywhere and convert to the local time zone when displaying dates/times to the user
    • UTC isn't perfect; aside from leap seconds, the biggest issue seems to be when local time zone rules change, making dates stored in UTC inaccurate
  • When passing timestamps over the wire (e.g. to/from an API), convert them to strings using an unambiguous standard format that includes the time zone such as ISO 8601
    • In TypeScript/JavaScript this can be accomplished using Date.toISOString(). Use new Date(dateString) to convert back into a Date object
  • In the cases where the time zone is set to UTC but a local timestamp is needed (e.g. to represent "today midnight"), a library may be needed: https://momentjs.com/docs/#/-project-status/recommendations/

new Date(2021, 10, 11) will return a date at midnight based on the current time zone

> process.env.TZ='UTC'
'UTC'
> new Date(2021, 10, 11)
2021-11-11T00:00:00.000Z

> process.env.TZ='America/New_York'
'America/New_York'
> new Date(2021, 10, 11)
2021-11-11T05:00:00.000Z

Alternative: explicit UTC timestamp

new Date('2028-11-05T04:00:00.000Z')
  • This doesn't change based on the value of TZ
  • But it may be a bit unclear that it represents midnight local time
  • The time offset may differ depending on whether daylight saving time is in effect or not

Alternative: explicit local timestamp

new Date('2028-11-05T00:00:00-04:00')
  • This doesn't change based on the value of TZ
  • It is clear that it represents midnight at some timezone
  • But it may not be fully clear if the represented time zone offset corresponds with the local time zone offset

It may be tempting to use setHours() to create a date that represents midnight local time; however, this also depends on the time zone:

> process.env.TZ='UTC'
'UTC'
> new Date(new Date().setHours(0, 0, 0, 0));
2021-11-17T00:00:00.000Z

> process.env.TZ='America/New_York'
'America/New_York'
> new Date(new Date().setHours(0, 0, 0, 0));
2021-11-17T05:00:00.000Z

Real-life example

The developer wants to create a date that represents "today at midnight local time":

const today = new Date();
today.setHours(0, 0, 0, 0);

If TZ is set to UTC and the local time zone offset is less than UTC (e.g. UTC - 4), then the final value of today will not be midnight local time, and the date will never be today (local time).

Alternative

???

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment