当输入为整数时,moment().isValid返回true。

4

代码:

  let modifiedValue = attribute_value;
  let isISOFormat = moment(new Date(attribute_value), moment.ISO_8601, true).isValid();
  if (isISOFormat) {
    modifiedValue = formatDateShortCustom(moment(attribute_value).toDate());
  }
  return modifiedValue;
};

在上面的代码中,属性值可以是:
  1. 2021-09-29T18:30:00.000Z
  2. 080921
我想确保当属性值为(1)格式时, 执行以下代码: modifiedValue = formatDateShortCustom(moment(attribute_value).toDate()); 然而,这个数字字符串也导致 isISOFormattrue,从而导致执行formatDateShortCustom方法,这不是我想要的。
我做错了什么吗?

1
整数是有效的时间戳,因为它可以表示从Unix纪元开始经过的秒数。如果您不希望允许数字字符串,请使用正则表达式进行检查,即 ^\d+$ - Terry
1
new Date(080921) 的输出结果为 Thu Jan 01 1970 01:01:20 GMT+0100(中欧标准时间)(至少在我的中欧控制台上是这样的 :))。 你将其传递给了 Moment。当然,Moment说这是一个有效的日期,这里没有什么奇怪的东西。 - Jeremy Thille
moment(new Date(attribute_value), moment.ISO_8601, true) 没有任何意义。 new Date(attribute_value) 返回一个日期对象,因此提供解析格式是多余的,没有什么需要解析(它已经在 new Date(...) 中完成)。严格参数也是一样,它不起作用。如果您想测试 attribute_value 是否符合 ISO 8601 格式,则应明确执行此操作,而不是尝试根据内置解析器对其执行的操作来推断是否符合要求。 - RobG
2个回答

2
我建议将此内容包装在一个名为isISOFormat()的函数中,并使用它来判断您的输入是否为ISO 8601日期字符串。
我还建议直接将输入传递给moment()构造函数,而不是先创建一个Date对象:

let attribute_values = ['2021-09-28T11:45:00Z', new Date().toISOString(), 20, null, '28/09/2021', 'is this a date?'];

function testIsISOFormat() {
    for(let attribute_value of attribute_values) {
        console.log(`isISOFormat(${attribute_value}):`, isISOFormat(attribute_value));
    }
}

function isISOFormat(input) {
    return moment(input, moment.ISO_8601, true).isValid();
}

console.log('Testing isISOFormat:');
testIsISOFormat()
.as-console-wrapper { max-height: 100% !important; top: 0; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.22.2/moment.min.js"></script>


0

moment.ISO_8601 在版本 2.7.0 以下是 undefined

这就是为什么无论您是否设置了严格解析选项,moment 都会尝试解析该值。 moment 检查字符串是否与 已知的 ISO 8601 格式 匹配。

我建议将格式作为第二个参数明确传递。

console.log(moment('2021-09-29T18:30:00.000Z', 'YYYY-MM-DDTHH:mm:ss.SSSZ', true).isValid());

console.log(moment('080921', 'YYYY-MM-DDTHH:mm:ss.SSSZ', true).isValid());
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.5.1/moment.min.js"></script>


moment.js文档允许您在moment 2.7.0+中指定moment.ISO_8601:https://momentjs.com/docs/#/parsing/special-formats/,例如:moment("2010-01-01T05:06:07", moment.ISO_8601); - Terry Lennox
1
谢谢指出。OP很可能在使用早于2.7.0版本的moment.js,其中moment.ISO_8601是未定义的。在2.7.0及以上版本中已定义了moment.ISO_8601,因此无法复现这种行为。 - Oluwafemi Sule
原因在于在将值分配给isISOFormat的表达式中,即moment(new Date(attribute_value), moment.ISO_8601, true)moment.js根本不解析该值,而是由内置解析器解析,然后将该结果(一个Date实例)传递给moment.js - RobG

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