如何正确地将无独立的日期(或者我猜是固定在HTML侧和JS侧的单个时区)的日期),从HTML DatePicker?p>我有以下简单代码,该代码产生了不正确的日期:
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中。
在<input type="date" />
元素中,所选日期以语言环境格式显示,但是value
属性始终以yyyy-mm-dd
格式返回,如MDN DOCS中所述。
换句话说,当您选择2019年3月9日时,您可能会在世界其他地区看到03/09/2019
或09/03/2019
,但是value
是CC_7,无论其任何时区域或本地化设置如何。这是一件好事,因为它允许您以标准ISO 8601格式使用所选日期,而无需尝试应用时间。
但是,当您使用Date
对象的构造函数(或使用Date.parse
)解析该格式的日期字符串时,您会违反已知问题:该日期不被视为本地时间,而将其视为UTC。这是ISO 8601的对面。
MDN文档中描述了这一点:
注意:使用日期构造函数(和
Date.parse
,它们是等效)的日期字符串解析,由于浏览器差异和不一致而被强烈劝阻。对RFC 2822格式字符串的支持仅是按照约定的。对ISO 8601格式的支持在仅日期的字符串(例如" 1970-01-01")中有所不同。
它也在ecmascript规范(重点是我的)中:
...当缺乏时区偏移时,仅日期表单被解释为UTC时间,而日期时间表格则将其解释为本地时间。
在2015年就此进行了辩论,但最终决定与现有行为保持兼容性比符合ISO 8601的兼容性更为重要。
回到您的问题,最好的办法是如果您不需要的话,将其解析为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);
}
请注意,最后的,12
将时间设置为中午而不是午夜。这是可选的,但是它避免了在午夜午夜过渡(巴西,古巴等)的本地时区中不存在午夜的情况。
然后是您的最后评论:
我真的只希望它假设所有输入和所有输出都在GMT中。
这与您显示的内容有些不同。如果您真的就是您想要的,那么您可以像以前一样构造Date
对象,并使用.toISOString()
,.toGMTString()
或.toLocaleString(undefined, {timeZone: 'UTC'})
function printDate(){
const d = new Date(document.getElementById("date").value); // will treat input as UTC
// will output as UTC in ISO 8601 format
alert(d.toISOString());
// will output as UTC in an implementation dependent format
alert(d.toGMTString());
// will output as UTC in a locale specific format
alert(d.toLocaleString(undefined, {timeZone: 'UTC'}));
}