Compare Dates from Rails to JavaScript

Viewed 261

I'm working on a feature of a project that changes the color of an element based on the date a record was created. I'm using a Rails Backend and React Frontend. I'm trying to make sure the color goes with the appropriate day and not the day before or after.

In Rails, I have a record where the created_at attribute is "2020-07-29 17:38:00.437423" (PST)

In React, that same record shows its created_at attribute as "2020-07-29T17:38:00.437Z"

1.

new Date("2020-07-29 17:38:00.437423")
//=> Wed Jul 29 2020 17:38:00 GMT-0700 (Pacific Daylight Time)
new Date("2020-07-29T17:38:00.437Z")
//=> Wed Jul 29 2020 10:38:00 GMT-0700 (Pacific Daylight Time)

I've noticed that when I remove the 'Z' in the second version, the time matches up as I expect, but why do these strings return date objects that show a 7-hour difference?

2 Answers

In the browser when you create a date without any timezone information it will actually assume that its in the system time zone:

new Date("2020-07-29 17:38:00.437423")
> Date Wed Jul 29 2020 17:38:00 GMT+0200 (Central European Summer Time)

In my case its GMT+0200 because I'm in Denmark. Ooops.

2020-07-29T17:38:00.437Z is actually a ISO8601 timestamp with a time zone designation which is a lot less ambiguous.

If the time is in UTC, add a Z directly after the time without a space. Z is the zone designator for the zero UTC offset. "09:30 UTC" is therefore represented as "09:30Z" or "0930Z". "14:45:15 UTC" would be "14:45:15Z" or "144515Z".
ISO8601 - Wikipedia

JavaScript's handling of dates and times is notoriously bad. When Brendan Eich rushed to create the language in 10 days back during the browser wars he just outright ripped off the date/time objects from java and the browser vendors created differing (awful) implementations. The result is a mess that still haunts us 25 years later.

There are multiple libraries like moment.js which fixes the problems and inconsistencies of the language as well as the lack of ways to convert from one TZ to another or manipulate dates.

<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.27.0/moment.min.js"></script>

I would really recommend Thoughtbot's excellent article It's About Time (Zones) for the backend-side of things.

max's answer is correct. I just wanted to offer clarification that Javascript can parse ISO8601 timestamps with a UTC offset, he just forgot a "0".

new Date("2020-07-29T17:38:00.437-07:00")
2020-07-30T00:38:00.437Z

Here is the specification for reference: https://tc39.es/ecma262/#sec-date-time-string-format

I would've just commented on his answer, but I don't have the reputation.

Related