从HTML日期选择器初始化JS日期对象:返回的日期不正确 [英] Initialize JS date object from HTML date picker: incorrect date returned

查看:182
本文介绍了从HTML日期选择器初始化JS日期对象:返回的日期不正确的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何从html datepicker中正确初始化与时区无关的日期(或者我猜一个固定在html端和JS端的单个时区的日期)?

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>

但至少在我的电脑上,目前在美国山区时间,它产生的日期不正确。我今天给它(2019年3月9日),它以下列格式提醒昨天的日期: Fri Mar 08 2019 17:00:00 GMT-0700(MST) 。我该怎么做呢?

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?

我真的只是想让它假设所有输入和所有输出都是GMT。

I really just want it to assume that all input and all output are in GMT.

推荐答案

< input type =date/> 元素中,所选日期以区域设置格式显示,但 value 属性始终以 yyyy-mm-dd 格式返回,如 MDN文档

In a <input type="date" /> element, the selected date is displayed in the locale format, but the value property is always returned in yyyy-mm-dd format, as described in the MDN docs.

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

In other words, when you choose March 9, 2019, you may see 03/09/2019 from the US or 09/03/2019 in other parts of the world, but value is 2019-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.

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

However, when you parse a date string in that format with the Date object's constructor (or with Date.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:


注意:强烈建议不要使用Date构造函数解析日期字符串(和 Date.parse ,它们是等效的)差异和不一致。对RFC 2822格式字符串的支持仅限于惯例。对ISO 8601格式的支持不同之处在于,仅日期字符串(例如1970-01-01)被视为UTC,而不是本地。

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.

它也是ECMAScript规范中的 (强调我的):

It's also in the ECMAScript specification (emphasis mine):


...当缺少时区偏移时,仅限日期的表格被解释为UTC时间和日期时间表格被解释为当地时间。

... 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.

2015年对此进行辩论,但最终决定保持与现有行为的兼容性比ISO更重要符合8601。

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:

function printDate(){
    const d = document.getElementById("date").value;
    alert(d);
}

如果你真的需要日期 object,那么最简单的选择是自己解析值:

If you really need a Date object, then the easiest option is to parse the value yourself:

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在午夜(巴西,古巴等)过渡的当地时区中午夜不存在的错误日期。

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.).

然后是你的最后评论:


我真的只是想让它假设所有输入和所有输出都是GMT。

I really just want it to assume that all input and all output are in GMT.

这与你所展示的有点不同。如果真的是你想要的,那么你可以像以前一样构造 Date 对象,并使用 .toISOString() .toGMTString(),或 .toLocaleString(undefined,{timeZone:'UTC'})

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'})

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'}));
}

这篇关于从HTML日期选择器初始化JS日期对象:返回的日期不正确的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆