您如何正确地从html datepicker初始化与时区无关的日期(或者我猜为在html端和JS端固定为单个时区的日期)?
我有以下简单的代码,生成的日期不正确:
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>
但是至少在我当前处于美国山区时间的计算机上,它会产生错误的日期。我提供了今天的日期(2019年3月9日),它以以下格式提醒昨天的日期:Fri Mar 08 2019 17:00:00 GMT-0700 (MST)
。我如何使其不这样做?
我真的只是希望它假设所有输入和所有输出都在GMT中。
答案 0 :(得分:1)
在<input type="date" />
元素中,所选日期以语言环境格式显示,但是value
属性始终以yyyy-mm-dd
格式返回,如the MDN docs中所述。
换句话说,当您选择2019年3月9日时,您可能会看到来自美国的03/09/2019
或世界其他地方的09/03/2019
,但是value
是{{1} },无论任何时区或本地化设置。这是一件好事,因为它使您可以使用标准ISO 8601格式处理选定的日期,而无需尝试花费时间。
但是,当您使用2019-03-09
对象的构造函数(或Date
)解析这种格式的日期字符串时,就会遇到一个已知问题:日期不被视为本地时间,但作为UTC。这是ISO 8601的相反。
对此内容进行了in the MDN docs的描述:
注意:由于浏览器的差异和不一致,强烈建议不要使用Date构造函数(和
Date.parse
等效)来解析日期字符串。仅按照约定,对RFC 2822格式字符串的支持。对ISO 8601格式的支持有所不同,因为仅日期字符串(例如“ 1970-01-01”)被视为UTC,而不是本地。
它也是in the ECMAScript specification(强调我的意思):
...如果不存在时区偏移,则仅日期形式被解释为UTC时间,而日期时间形式被解释为本地时间。
有a debate about this in 2015,但最终决定保持与现有行为的兼容性比遵守ISO 8601更重要。
回到您的问题,最好的方法是不将其解析为Date.parse
对象(如果不需要)。换句话说:
Date
如果您确实需要一个function printDate(){
const d = document.getElementById("date").value;
alert(d);
}
对象,那么最简单的选择就是自己解析该值:
Date
请注意,最后的function printDate(){
const parts = document.getElementById("date").value.split('-');
const d = new Date(+parts[0], parts[1]-1, +parts[2], 12);
alert(d);
}
将时间设置为中午,而不是午夜。这是可选的,但可以避免DST在午夜转换的本地时区(巴西,古巴等)不存在午夜的情况。
然后是您的最后一条评论:
我真的只是希望它假设所有输入和所有输出都在GMT中。
与您显示的内容有些不同。如果确实是您想要的,那么可以像以前一样构造,12
对象,并使用Date
,.toISOString()
或.toGMTString()
.toLocaleString(undefined, {timeZone: 'UTC'})