如何在没有正则表达式的情况下安全地区分 ISO 8601 字符串和在 queryParams 中存储为字符串的数字

how to safely distinguish ISO 8601 string and number stored as string in queryParams without regex

例如,我有一个日期和金额 属性 存储在 url als 查询参数中

...?date=2019-06-12T06:20:39.465Z&amount=20000

我希望能够解析所有查询参数并使用 javascript 将它们分配给正确的类型。

目前我正在使用

        paramMap.keys.forEach(key => {
            let value: any = paramMap.get(key);
            if (isFinite(Date.parse(value))) {
                // keep as string
            } else if (isFinite(parseInt(value, 10))) {
                value = isInteger(value) ? parseInt(value, 10) : parseFloat(value);
            } else if (value === 'true' || value === 'false') {
                value = value === 'true';
            }
            obj[key] = value;
        });
        return obj;

在这种情况下,amount=20000 将被 Date.parse 识别。

还有

2019-06-12T06:20:39.465Z 将使用 parseInt 解析为 2019...

isFinie、parseInt 和 isInteger 是从 lodash 导入的。

如果可能我不想使用正则表达式。

编辑:请假设我不知道密钥的名称。因此该脚本应该适用于所有属性。

ISO 可能会忽略秒、时区或毫秒,但如果您忽略这些并检查其他所有内容,您就可以可靠地检查不同的 ISO 格式。

console.log(isISO('2019-06-12T06:20:39.234Z'))
console.log(isISO('2019-06-12T06:20:39'))
console.log(isISO('2019-06-12T06:20'))

console.log(isISO("2019-1-1"))
console.log(isISO('2019-06-12T06:20:39+05'))

console.log(isISO('ketchup'))

function isISO(str) {
  try {
    str = str.split('+')[0];
    var iso = new Date(str).toISOString();
    var [date, time] = iso.split('T');
    var [y, m, d] = date.split('-');
    return iso.indexOf(`${y}-${m}-${d}`) === 0;
  } catch (e) {
    return false;
  }
}

使用 + operator, the Number function, or lodash's _.toNumber() 将 return NaN 用于带混合数字的字符串:

console.log(+'2019-06-12T06:20:39.465Z')

console.log(+'20000')

所以逻辑是:

const parseParam = value => {
  let v = +value

  if (!isNaN(v)) return v

  v = Date.parse(value)

  if (!isNaN(v)) return v

  if (value === 'true' || value === 'false') return value === 'true'

  return value
}

console.log(parseParam('2019-06-12T06:20:39.465Z'))
console.log(parseParam('20000'))
console.log(parseParam('false'))
console.log(parseParam('cats'))