How do you correctly intitialize a timezone-independent date (or I guess a date that is fixed to a single timezone across the html side and the JS side) from a html datepicker?
I have the following simple code, which is producing incorrect dates:
function printDate(){
let d = new Date(document.getElementById("date").value)
alert(d)
}
document.getElementById("printDate").addEventListener("click", e => printDate())
<html>
<body>
Print Date: <br><input type="date" id="date"> <button id="printDate">Add</button>
</body>
</html>
But at least on my computer, currently sitting in U.S. mountain time, it produces incorrect dates. I give it today's date (March 9, 2019), and it alerts yesterday's date in the following format: Fri Mar 08 2019 17:00:00 GMT-0700 (MST)
. How do I make it not do that?
I really just want it to assume that all input and all output are in GMT.
In a
<input type="date" />
element, the selected date is displayed in the locale format, but thevalue
property is always returned inyyyy-mm-dd
format, as described in the MDN docs.In other words, when you choose March 9, 2019, you may see
03/09/2019
from the US or09/03/2019
in other parts of the world, butvalue
is2019-03-09
regardless of any time zone or localization settings. This is a good thing, as it allows you to work with the selected date in a standard ISO 8601 format, without trying to apply a time.However, when you parse a date string in that format with the
Date
object's constructor (or withDate.parse
), you run up against a known issue: The date is not treated as local time, but as UTC. This is the opposite of ISO 8601.This is described in the MDN docs:
It's also in the ECMAScript specification (emphasis mine):
There was a debate about this in 2015, but ultimately it was decided that maintaining compatibility with existing behaviors was more important than being ISO 8601 compliant.
Going back to your question, the best thing to do would be to not parse it into a
Date
object if you don't need one. In other words:If you really need a
Date
object, then the easiest option is to parse the value yourself:Note the
,12
at the end sets the time to noon instead of midnight. This is optional, but it avoids situations of getting the wrong day when midnight doesn't exist in the local time zone where DST transitions at midnight (Brazil, Cuba, etc.).Then there's your last comment:
That's a bit different than what you showed. If really that's what you want, then you can construct the
Date
object as you previously did, and use.toISOString()
,.toGMTString()
, or.toLocaleString(undefined, {timeZone: 'UTC'})