Suppose you have a time: April 3, 2017, at midnight Pacific Time. You want to express it as UTC in ISO 8601 format, for instance to send it over the wire as JSON. The result is
"2017-04-03T07:00:00.000Z". Note the 07:00. Pacific Time is -8 hours from UTC during Standard Time, and -7 hours during Daylight Savings Time. April 3 falls in Daylight Savings Time.
Now suppose we change the year: April 3, 1969, still at midnight Pacific Time. DST started later that year, so now the answer is
"1969-04-03T08:00:00.000Z". But if we run
new Date(1969, 3, 3).toISOString() your browser gives us:
. That might look correct, or you might see a 07:00 again.
Right now, some browsers do the right thing (ignore the old spec), some do the wrong thing (follow the old spec), and it also depends on what version you’re running. It even seems to depend on what year you’re asking about. For instance modern Chrome seems to give me the right answers back to 1970, but then is wrong before that. Also, even if your browser does the wrong thing, you might still get lucky based on the current year and the date you’re trying to build. I wrote a jsbin page you can load in multiple browsers to see if they agree.
I think the only safe answer is to use moment-timezone to build your dates. For instance if you know the timezone:
moment.tz([y, m, d], tz)
or if you don’t:
moment.tz([y, m, d], moment.tz.guess())
(And don’t forget the
m is off by one.)
If you need to force that back into a regular
Date object, you could do:
new Date(moment.tz([y, m, d], tz).toJSON())
Just make sure that you’re using
moment-timezone-with-data.js, not plain
moment-timezone.js, or you’ll still be relying on the browser’s own idiosyncratic behavior.
I hope this is helpful to someone. If your users enter birthdays with some kind of date picker, you probably suffer from this bug!blog comments powered by Disqus Prev: Postgres isn't running the archive_command on my standby Next: What to Learn