JacobTheDev
JacobTheDev

Reputation: 18510

Getting the timezone a simplified ISO 8601 date string

I have two date strings, each in a different time zone. These strings are in what I believe is referred to as "simplified" ISO 8601 format. Two example dates are listed below.

The first date is in CDT while the second date is in UTC. I believe the last four digits of each of these strings indicates the time zone.

What's weird is when I set up new Date() for each of these, I'm getting incorrect dates reported via console.log(). For example:

const local_date = new Date("2017-08-14T18:41:52.793Z");
const remote_date = new Date("2017-08-14T23:41:52.000Z");

console.log("local_date = " + local_date);
console.log("remote_date = " + remote_date);

Outputs:

local_date = Mon Aug 14 2017 13:41:52 GMT-0500 (Central Daylight Time)
remote_date = Mon Aug 14 2017 18:41:52 GMT-0500 (Central Daylight Time)

It appears as though the first date is getting 5 hours subtracted even though the source date was provided in CDT; it's like it's assuming that both dates are provided in UTC.

https://jsfiddle.net/nkax7cjx/1/

What am I don't wrong here?

Upvotes: 2

Views: 8416

Answers (2)

Stephen R. Smith
Stephen R. Smith

Reputation: 3400

The last four digits are 3 digit milliseconds followed by the timezone, where Z indicates UTC time, and +hh:mm and -hh:mm indicates the offset from UTC time.

So 793Z is 793 milliseconds in UTC.

So both of your examples are in UTC, which is why you're seeing the output you're seeing.

const local_date = new Date("2017-08-14T18:41:52.793-05:00");

Would be CDT format.

Upvotes: 3

user7605325
user7605325

Reputation:

The last digits, as already explained in @Stephen's answer, are the milliseconds. So, 52.793 means 52 seconds and 793 milliseconds.

Both dates are in UTC, because the Z in the end is the UTC designator.

Central Daylight Time (CDT) is 5 hours behind UTC, so you should use -05:00 instead of Z:

new Date("2017-08-14T18:41:52.793-05:00")

Note: short names like CDT and CST are not real timezones. They are abbreviations used by more than one timezone.

That's because a timezone is a set of all offsets that a region had, has and will have during its history. Different regions adopted CST (Central Standard Time) and CDT (Central Daylight Time) at different times, so their history of offsets are not the same. That's why there are so many timezones, and the fact that all use CST/CDT today doesn't mean that all used nor will use the same forever.

The ideal is to always work with IANA timezones names (always in the format Region/City, like America/Chicago or Europe/Berlin). Avoid using the 3-letter abbreviations (like CST or PST) because they are ambiguous and not standard.

Unfortunately, plain javascript doesn't have a great support to timezones, but you can use momentjs timezone to deal with it.

If the date and time are in a specific timezone, you could do:

moment.tz('2017-08-14T18:41:52.793', 'America/Chicago')

This will result in a date equals to 2017-14-08T18:41:52.793-05:00 (CDT).

The great advantage of using a full timezone name (like America/Chicago) is that Daylight Saving Time effects are handled automatically. If I take a date in January, when DST is not in effect:

moment.tz('2017-01-14T18:41:52.793', 'America/Chicago')

The result is a date equivalent to 2017-14-01T18:41:52.793-06:00 (CST). Note that the offset changed automatically to -06:00, because in January DST is not in effect in Chicago timezone. This automatic behaviour is not possible using fixed offsets.

You can get a list of all timezones (and choose accordingly) using moment.tz.names().

Upvotes: 6

Related Questions