如何将日期输入和时间输入视为当地时间,而不是世界时间?

2024-03-22

用户输入的日期输入2019-12-22给出这些值:

  • input.value: "2019-12-22"
  • input.valueAsNumber: 1576972800000
  • input.valueAsDate: "Sat Dec 21 2019 16:00:00 GMT-0800 (Pacific Standard Time)"
    • 这个结果日期对象似乎是错误的
    • 当浏览器返回一个值时,它将用户输入视为世界时间
    • 因此日期对象的 utc 表示形式与输入显示给用户的内容相同
    • input.valueAsDate.getUTCDate()回报22,这是用户输入的内容
    • input.valueAsDate.getDate()回报21,不是用户输入的内容
    • 因此我们得出结论,日期输入显示并接受 UTC 时间,而不是本地时间

我们想要得到的结果date.toString()显示与日期输入中原始用户输入相同的结果

我们如何允许用户与当地时间交互,然后在脚本中获取正确的日期对象?


此问题是由 TC-39 决定将仅限日期的 ISO 8601 格式时间戳视为 UTC 引起的,而与 ISO 8601 保持一致并将其视为本地时间戳更为合乎逻辑。看为什么 Date.parse 给出不正确的结果? https://stackoverflow.com/questions/2587345/why-does-date-parse-give-incorrect-results

简单的解决方案是手动解析字符串,不要使用内置解析器,作为至少一种当前实现,直到最近将 YYYY-MM-DD 解析为本地。另外,请勿使用当前时区偏移量来调整时间值,因为这不允许偏移量的历史变化或可能的夏令时变化。

// Parse timestamp in YYYY-MM-DD format as local
function parseISOLocal(s) {
  let [y, m, d] = s.split(/\D/);
  return new Date(y, --m, d);
}

// Format date as YYYY-MM-DD local
function formatISOLocal(d) {
  let z = n => (n<10?'0':'') + n;
  return d.getFullYear() + '-' + z(d.getMonth()+1) + '-' + z(d.getDate());
}

let s = '2019-12-22';
let d = parseISOLocal(s);
console.log( d.toString());
console.log( formatISOLocal(d));

Edit

在支持输入类型日期且 YYYY-MM-DD 按 ECMA-262 解析为 UTC 的情况下,您可以使用值作为日期和 UTC 方法。但是,并非所有浏览器都支持输入类型日期,并且并非所有解析器都会将该格式解析为 UTC。

不依赖输入类型日期并手动解析值、检查格式和有效性要可靠得多。这是通常使用日期小部件和库而不是内置日期功能的原因之一。

let inp = document.getElementById('dob');
let dobObj = inp.valueAsDate;
let dobStr = inp.value;

console.log('Value as date: ' + dobObj);   // Safari: null
console.log('Value as string: ' + dobStr); // 2018-06-15
<input id="dob" type="date" value="2018-06-15">
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何将日期输入和时间输入视为当地时间,而不是世界时间? 的相关文章