【问题标题】:ISO Date Being Sent Incorrectly Because of DST由于 DST,ISO 日期发送不正确
【发布时间】:2019-04-29 17:28:06
【问题描述】:

我们应用程序中的一个组件允许用户输入他们的生日,然后再显示它。它适用于大多数情况,但对于某些用例存在问题,我怀疑是因为夏令时。

我以 ISO 格式(UTC 时间)将日期发送到后端,并以 ISO 格式接收它,但带有相对时间。示例(8. 8. 2000):

sending: 2000-08-07T22:00:00.000Z
receiving: 2000-08-08T00:00:00+02:00

对于某些日期,返回的日期会低一天。示例(8. 8. 1977,变为 7. 8. 1977):

sending: 1977-08-07T23:00:00.000Z
receiving: 1977-08-08T00:00:00+02:00

我有一个理论,这是因为客户端和服务器使用不同的语言环境 - 历史上对 DST 的观察方式不同。我在捷克共和国工作,该国在 1977 年没有实行 DST。

我该如何解决这个问题?如果我的理论是正确的,我如何找出正在使用的语言环境以及如何设置前端/客户端?

提前致谢!

【问题讨论】:

  • 您始终可以只来回发送日期本身(ISO 8601 为 YYYY-MM-DD)。但作为一项测试,只需在一天中间选择一个时间,任何时间增加或减少一个小时都不会影响一天,然后尝试一下。例如上午 10 点。
  • 您的两个示例中的日期对实际上都具有相同的日期,只是格式不同。简而言之,没有错,所有 4 个日期都是准确的。您需要在区域设置感知输出中序列化日期,以便在特定区域设置的时间中获取日期。一旦你这样做了,你会看到日期是相同的,即使它们在以 UTC 记录时看起来有所变化。
  • 这两个日期是相同的,除了第一个在字符串中间有TimeZone,其中received在最后有TZ。您需要选择要使用的。

标签: javascript date utc


【解决方案1】:

您不必了解语言环境!我们正在谈论日期。您需要构建和传输日期,这样语言环境就不会成为问题。为此,您的日期需要代表 UTC 午夜。查看您的示例,您的发送日期和接收日期都不符合此条件,因此我认为您可能会发疯。

希望this answer 能为您提供有用的信息。

【讨论】:

  • 谢谢,您链接的答案很有帮助!
  • 这不是答案。如果引用的答案回答了这个问题,您应该将此问题标记为重复。如果 OP 只想处理日期而不是时间,他们应该只传输日期,而不是时间。在半个世界中,“午夜 UTC”是时区偏移期间与当前本地日期不同的日期。
【解决方案2】:

如果你只想处理日期,那么不要使用时间组件,只传输日期,例如2000-08-07。

不幸的是,TC39 提出了bad decision,决定将 ISO 8601 仅日期格式 YYYY-MM-DD 解析为 UTC,而不是遵循 ISO 8601 并将其视为本地。这个决定似乎是出于商业动机,而不是遵循常识。

但无论如何,您可以通过自己解析和创建日期以 ISO 8601 仅日期格式发送和接收日期。这只是几行代码,在其他地方已经回答了很多次,但这里有一些简单的功能:

function parseISODate(s) {
  var [y, m, d] = s.split(/\D/);
  return new Date(y, m-1, d);
}
function formatISODate(date) {
  let z = n => (n<10?'0':'')+n;
  return date.getFullYear() + '-' +
         z(date.getMonth()+1) + '-' +
         date.getDate();
}

let s = '2000-08-31';
let d = parseISODate(s);
console.log(d.toLocaleString());
console.log(formatISODate(d));

【讨论】:

    猜你喜欢
    • 2018-04-15
    • 2014-04-13
    • 1970-01-01
    • 2012-02-02
    • 1970-01-01
    • 1970-01-01
    • 2020-11-05
    • 1970-01-01
    • 2012-10-08
    相关资源
    最近更新 更多