如何将PostgreSQL的timestamptz转换为JavaScript日期?

3
我的数据库使用`now()::TEXT`函数创建了一堆`timestamptz`值。在多个 API 调用中,我会接收到这些值,但我很难将它们转换成 JavaScript 的日期对象。
以下是一个 PostgreSQL 返回的 `timestamptz` 字符串示例:`2019-09-12 09:52:52.992823+00`。
问题在于,如果我试图执行 `new Date("2019-09-12 09:52:52.992823+00")`,那么浏览器会有一些棘手的行为。看起来我必须先在字符串前面加上一个 "Z" 才能得到正确的时间(因为时区?)
此外,Firefox似乎根本不解析它(但Chrome可以)。如果我删除 "+00",它似乎也能工作。
所以我想出了这种“解决方案”,它似乎在两个浏览器上都能工作,但在使用日期之前必须对所有日期调用它,而且它似乎有点脆弱。这是正确的方式吗?
function fixDate(date) {
  return date.replace("+00", "") + "Z";
}
1个回答

2
内置解析器支持的格式在ECMA-262中有所描述,这基本上是ISO 8601的一个特定子集和Date.prototype.toString指定的格式。对于任何其他格式(即,任何不与指定格式完全匹配的内容),解析是依赖于实现的,不应被信任。
您可以考虑解析字符串并构造符合ECMA-262的新字符串,例如将“2019-09-12 09:52:52.992823+00”转换为“2019-09-12T09:52:52.992+00:00”。

// Convert 2019-09-12 09:52:52.992823+00 to
//         2019-09-12T09:52:52.992+00:00
// Assumes all strings are +00:00
function rectifyFormat(s) {
  let b = s.split(/\D/);
  return b[0] + '-' + b[1] + '-' + b[2] + 'T' +
         b[3] + ':' + b[4] + ':' + b[5] + '.' +
         b[6].substr(0,3) + '+00:00';
}

let s = '2019-09-12 09:52:52.992823+00';
console.log(new Date(rectifyFormat(s)))

然而,即使是支持的格式,也要遵循避免使用内置解析器的一般建议。将字符串解析为另一个字符串,再解析为日期似乎也是低效的。最好编写自己的解析函数(只需几行代码)或使用库,例如:

// Parse string like '2019-09-12 09:52:52.992823+00'
// to a date
// Assumes string is always +00
function myDateParse(s) {
  let b = s.split(/\D/);
  --b[1];                  // Adjust month number
  b[6] = b[6].substr(0,3); // Microseconds to milliseconds
  return new Date(Date.UTC(...b));
}

let s = '2019-09-12 09:52:52.992823+00';
console.log(myDateParse(s).toISOString());


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接