javascript - 从 HTML 日期选择器 : incorrect date returned 初始化 JS 日期对象

标签 javascript html date timezone locale

如何从 html 日期选择器正确初始化与时区无关的日期(或者我猜是固定到 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 时间。

最佳答案

<input type="date" /> 中元素,所选日期以语言环境格式显示,但 value属性总是在 yyyy-mm-dd 中返回格式,如 the MDN docs 中所述.

换句话说,当您选择 2019 年 3 月 9 日时,您可能会看到 03/09/2019来自美国或09/03/2019在世界其他地方,但是value2019-03-09无论任何时区或本地化设置如何。这是一件好事,因为它允许您以标准 ISO 8601 格式处理所选日期,而无需尝试应用时间。

但是,当您使用 Date 解析该格式的日期字符串时对象的构造函数(或使用 Date.parse ),您会遇到一个已知问题:日期未被视为本地时间,而是被视为 UTC。这是 ISO 8601 的相反

这描述了in the MDN docs :

Note: parsing of date strings with the Date constructor (and Date.parse, they are equivalent) is strongly discouraged due to browser differences and inconsistencies. Support for RFC 2822 format strings is by convention only. Support for ISO 8601 formats differs in that date-only strings (e.g. "1970-01-01") are treated as UTC, not local.

也是in the ECMAScript specification (强调我的):

... When the time zone offset is absent, date-only forms are interpreted as a UTC time and date-time forms are interpreted as a local time.

a debate about this in 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最后将时间设置为中午而不是午夜。这是可选的,但它避免了在 DST 在午夜转换的本地时区(巴西、古巴等)不存在午夜时得到错误日期的情况。

然后是你最后的评论:

I really just want it to assume that all input and all output are in 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'}));
}

关于javascript - 从 HTML 日期选择器 : incorrect date returned 初始化 JS 日期对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55083314/

相关文章:

android/java se SimpleDateFormat 时区问题

ios - 通知每分钟触发 6 次(swift4)

javascript - 我得到 "cannot set property ' innerHTML' of null

html - 为什么我的 UL 子菜单采用其祖 parent 的背景?

javascript - 为什么即使必填字段留空也会提交此表单?

html - Angularjs 菜单改变主体顶部位置?

javascript - 如何在单词下方使用底部边框,长度有限且居中?

SQLite:如何从出生日期计算年龄

javascript - ES6 类扩展数组 : workaround for ES5 Babel transpile

javascript - iPad 底部 :0px issue