Date.toISOString() 但本地时间而不是 UTC

2022-01-16 00:00:00 datetime date timezone javascript

假设我们有这个日期时间:

Let's say we have this datetime:

var d = new Date("Sat Jul 21 2018 14:00:00 GMT+0200");

将其导出为字符串 (console.log(d)) 会导致浏览器之间的结果不一致:

Exporting it as a string (console.log(d)) gives inconsistent results among browsers:

  • 2018 年 7 月 21 日星期六 14:00:00 GMT+0200(巴黎,马德里(heure d'été)) 使用 Chrome

2018 年 7 月 21 日星期六 14:00:00 UTC+0200 使用 Internet Explorer 等

Sat Jul 21 14:00:00 UTC+0200 2018 with Internet Explorer, etc.

因此我们无法将日期时间发送到具有格式不一致的服务器.

so we can't send datetime to a server with an unconsistent format.

那么自然的想法是要求 ISO8601 日期时间,并使用 d.toISOString(); 但它给出了 UTC 日期时间:2018-07-21T12:00:00.000Z 而我想要的是本地时区时间:

The natural idea then would be to ask for an ISO8601 datetime, and use d.toISOString(); but it gives the UTC datetime: 2018-07-21T12:00:00.000Z whereas I would like the local-timezone time instead:

2018-07-21T14:00:00+0200
or
2018-07-21T14:00:00

如何获得这个(不依赖像momentjs这样的第三方依赖)?

我试过这个,似乎可行,但没有更自然的方法吗?

var pad = function(i) { return (i < 10) ? '0' + i : i; };

var d = new Date("Sat Jul 21 2018 14:00:00 GMT+0200");
Y = d.getFullYear();
m = d.getMonth() + 1;
D = d.getDate();
H = d.getHours();
M = d.getMinutes();
S = d.getSeconds();
s = Y + '-' +  pad(m) + '-' + pad(D) + 'T' + pad(H) + ':' + pad(M) + ':' + pad(S);
console.log(s);

推荐答案

ECMA-262 对使用时区格式化日期字符串的内置支持有限,存在依赖于实现的 toString 和 toLocaleString 方法或 toISOString,它始终是 UTC.如果 toISOString 允许一个参数来指定 UTC 或本地偏移量(默认为 UTC),那就太好了.

There is limited built-in support for formatting date strings with timezones in ECMA-262, there is either implementation dependent toString and toLocaleString methods or toISOString, which is always UTC. It would be good if toISOString allowed a parameter to specify UTC or local offset (where the default is UTC).

编写自己的函数来生成符合 ISO 8601 且具有本地偏移量的时间戳并不困难:

Writing your own function to generate an ISO 8601 compliant timestamp with local offset isn't difficult:

function toISOLocal(d) {
  var z  = n =>  ('0' + n).slice(-2);
  var zz = n => ('00' + n).slice(-3);
  var off = d.getTimezoneOffset();
  var sign = off > 0? '-' : '+';
  off = Math.abs(off);

  return d.getFullYear() + '-'
         + z(d.getMonth()+1) + '-' +
         z(d.getDate()) + 'T' +
         z(d.getHours()) + ':'  + 
         z(d.getMinutes()) + ':' +
         z(d.getSeconds()) + '.' +
         zz(d.getMilliseconds()) +
         sign + z(off/60|0) + ':' + z(off%60); 
}

console.log(toISOLocal(new Date()));

相关文章