【问题标题】:Parsing ISO-8601 date containing TZ offset with seconds用秒解析包含 TZ 偏移量的 ISO-8601 日期
【发布时间】:2021-10-19 05:11:15
【问题描述】:

似乎在 Javascript 中定义 ISO 日期格式存在问题。据我了解,ISO 格式的日期可以包括 TZ 偏移量,包括小时、分钟和秒,例如:

1919-07-01T00:00:00+04:31:19

尝试使用 JavaScript new Date() 对象解析此类日期时间字符串会导致错误:

new Date('1919-07-01T00:00:00+04:31:17').toLocaleDateString('ru-RU') => "Invalid Date"
new Date('1919-07-01T00:00:00+04:31').toLocaleDateString('ru-RU') => "01.07.1919"

示例中指定的日期来自 Java 后端客户端/POSTGRESQL 数据库,其中表示“1919-07-01T00:00:00+04:31:17”被视为有效的 ISO 日期。 如果我们查看以下有关夏令时更改的数据,则可以理解日期在时区偏移中包含“秒”的原因: https://www.timeanddate.com/time/change/russia/moscow?year=1919

是否有任何建议为什么无法克服此限制或问题的根源在哪里?

【问题讨论】:

  • en.wikipedia.org/wiki/ISO_8601#Times 并没有说秒在时区有效。 1919-07-01T00:00:00+04:31:19 是无效的日期字符串。
  • 时区莫斯科时间/UTC+03:00。问题是对于低于 01.07.1919 的日期,它将具有偏移 +04:31:17
  • @evolutionxbox Wiki 说“ISO 8601 中的时区表示为本地时间(未指定位置)、UTC 或与 UTC 的偏移量。”不幸的是,我没有找到在线可用的原始 ISO 规范文本
  • ISO 8601 可能不会在 UTC 偏移中指定秒数,这就是解析器不“期望”它的原因 - 然而,存在这样的偏移,对于给定的 tz,另请参阅 @987654323 中的相应部分@ 代表欧洲/莫斯科
  • 用法:那些秒与闰秒无关。

标签: javascript postgresql datetime


【解决方案1】:

似乎在 Javascript 中定义 ISO 日期格式存在问题。

Javascript 基于ECMA-262,由 ECMA International 发布。 ISO 8601 由不同的标准组织 ISO 发布。我没有 ISO 8601 的完整副本,但我希望有扩展允许偏移量中的秒数,因为它们在 1900 年之前相当普遍。

ECMA-262 定义了几种格式,one is based on a simplification of ISO 8601,因此不支持 ISO 8601 支持的所有格式(另一种是 toString 生成的格式)。

由于 OP 中的格式与 ECMA-262 中的格式之一不一致,因此解析依赖于实现,请参阅Why does Date.parse give incorrect results?

您最好的选择是手动解析字符串,使用简单的函数或支持偏移秒数的库。

下面是一个示例解析函数(根据timeanddate,1919 年偏移的秒部分应该是 19,而不是 17,所以我已经相应地修改了原始字符串):

// Parse format 1919-07-01T00:00:00+04:31:19
function parseWithTZSecs(date) {
  let [Y, M, D, H, m, s, oH, om, os] = date.match(/\d+/g);
  let sign = date.substring(19,20) == '+'? -1 : 1;
  return new Date(Date.UTC(Y, M-1, D, +H + sign*oH, +m + sign*om, +s + sign*os));
}

let date = parseWithTZSecs('1919-07-01T00:00:00+04:31:19');
// 1919-07-01, 12:00:00 AM
console.log(date.toLocaleString('en-CA',{timeZone: 'Europe/Moscow'}));

这只是一个例子,当然它应该对输入进行验证并处理意外的格式和值。

【讨论】:

    猜你喜欢
    • 2013-05-14
    • 1970-01-01
    • 2011-06-17
    • 2021-01-17
    • 1970-01-01
    • 2013-04-26
    • 1970-01-01
    • 2021-12-15
    相关资源
    最近更新 更多