Javascript - 枚举对象中的键、值对并转换匹配 ISO 时间戳格式的那些

问题描述

概述:我有一个对象数组 (arr)。我需要将看起来像 ISO 时间戳的对象中的任何值转换为纪元。我通过正则表达式匹配。

我有一个看起来像的对象:

{
    assignee: null
    color: null
    description: "cool object"
    id: "12234858"
    last_updated: "2021-01-22T15:30:10.495000+00:00"
}

我有一些代码可以执行以下操作:

arr.forEach((item) => {
    let regex = /^[+-]?\d{4}(-[01]\d(-[0-3]\d(T[0-2]\d:[0-5]\d:?([0-5]\d(\.\d+)?)?[+-][0-2]\d:[0-5]\dZ?)?)?)?/;
    Object.entries(myobject).forEach(([key,value]) => {
        if (value !== null) {
            if (value.match(regex)) {
                value = Date.parse(value) / 1000;
            }
        }
    });
});

日期转换在迭代每个对象的键和值时起作用,但是一旦 arr.forEach() 完成,这些值就会重置。处理这些转换的最佳方法是什么?我应该映射到新对象并复制吗?

解决方法

值本身是一个原语,它不保留与它所取自的对象的“连接”。您需要使用已解构的键将值分配回项目。

注意:您的正则表达式实际上不起作用,并将其他值检测为日期。解析并检查值是否为 NaN 会更容易。请参阅此answer

const arr = [{
  assignee: null,color: null,description: "cool object",id: "12234858",last_updated: "2021-01-22T15:30:10.495000+00:00",}];

arr.forEach((item) => {
  Object.entries(item).forEach(([key,value]) => {
    if (!isNaN(Date.parse(value || ''))) {
      // assign the new value back to the original item
      item[key] = Date.parse(value) / 1000;
    }
  });
});

console.log(arr);

@NicholasCarey's comment 所述,!isNaN(Date.parse()) 可能会将其他字符串标识为日期。因此,如果您遇到误报,您可能需要使用正则表达式(取自此 answer)或更严格的库:

const arr = [{
  assignee: null,}];

const regex = /\d{4}-[01]\d-[0-3]\dT[0-2]\d:[0-5]\d:[0-5]\d\.\d+([+-][0-2]\d:[0-5]\d|Z)/;

arr.forEach((item) => {
  Object.entries(item).forEach(([key,value]) => {
    if (regex.test(value || '')) {
      // assign the new value back to the original item
      item[key] = Date.parse(value) / 1000;
    }
  });
});

console.log(arr);

,

我会使用像 Luxon 这样的库。像这样:

const {DateTime} = require('luxon');

function transformIso8601ToSomethingUsable(arr) {
  for ( const obj of arr ) {
    for ( const [k,v] of Object.entries(obj) ) {
      obj[k] = iso8601DateTime2epochTime(v);
    }
  }
}

function iso8601DateTime2epochTime(s) {
  const dt = DateTime.fromISO(s).toUTC();
  const epochTime = dt.isValid
    ? Math.round(dt.toSeconds())
    : s ;
  return epochTime;
}

然后你可以这样说

const arr = [{
  assignee: null,}];

transformIso8601ToSomethingUsable(arr);

并得到

[
  {
    "assignee": null,"color": null,"description": "cool object","id": "12234858","last_updated": 1611329410
  }
]