如何使用 date-fns 验证日期字符串

How to validate a date string using date-fns

提问人:dokgu 提问时间:11/9/2023 更新时间:11/9/2023 访问量:48

问:

我正在尝试使用 date-fns 验证 datetime 的用户输入:

import { isDate, isValid } from 'date-fns';

console.log('DATE:', stringVal);
console.log('IS_DATE:', isDate(new Date(stringVal)));
console.log('IS_VALID:', isValid(new Date(stringVal)));

这将产生:

DATE: 2023-02-31 03:03:03
IS_DATE: true
IS_VALID: true

这似乎是不正确的,因为 2023 年 2 月 31 日不是有效日期。验证 ISO 日期字符串的正确方法是什么?

JavaScript 时间 验证 日期 - FNS

评论


答:

0赞 dokgu 11/9/2023 #1

看起来我可以使用parseISO函数:

import { isDate, isValid, parseISO } from 'date-fns';

if (!isDate(parseISO(stringVal)) || !isValid(parseISO(stringVal))) {
  throw new Error('Invalid date value');
}

评论

0赞 Timothy Jones 11/9/2023
这将起作用,但我认为代码有点误导,因为您的字符串实际上不是有效的字符串。我推荐了一个更严格的库,并且还提供了更好的反馈,说明为什么解析在另一个答案中失败。ISO
1赞 Timothy Jones 11/9/2023 #2

这里发生了几件事。

在您致电时,日期已更正isValid

您正在查看 的返回值是否为有效日期。此时,日期字符串中的问题已得到纠正。new Date('2023-02-31 03:03:03')

console.log('DATE:', new Date(stringVal)); // Fri Mar 03 2023 03:03:03 
console.log('IS_DATE:', isDate(new Date(stringVal))); // yes, Mar 03 is a date
console.log('IS_VALID:', isValid(new Date(stringVal))); // yes, Mar 03 is valid

构造函数非常乐观 - 允许实现以他们喜欢的方式解析意外的格式Date

Date.parse() 和 Date() 构造函数都接受日期时间字符串格式的字符串作为输入。此外,当输入与此格式不匹配时,允许实现支持其他日期格式。

您需要使用不同的解析函数。

您的字符串不是 ISO 日期格式。

您的字符串有空格,并且缺少用于分隔时间和日期部分的指示器。它应该是 .理想情况下,它还应该包括时区信息。T2023-02-31T03:03:03


修复

我推荐 luxon,因为它对格式很严格,并为您提供了日期未解析的明确原因:DateTime.fromISO

const maybeDate = DateTime.fromISO(`2023-02-31T03:03:03`);
if(maybeDate.invalid) {
   console.log(maybeDate.invalid.reason); // unit out of range
   console.log(maybeDate.invalid.explanation) // you specified 31 (of type number) as a day, which is invalid
}

请注意,如果您将它与原始字符串一起使用,则会得到

the input "2023-02-31 03:03:03" can't be parsed as ISO 8601

因为原始字符串不是 ISO 格式。如果有效日期以非 ISO 格式编写,您也会收到此错误:

DateTime.fromISO(`2023-02-28 03:03:03`)
// the input "2023-02-28 03:03:03" can't be parsed as ISO 8601

评论

0赞 RobG 11/12/2023
日期和时间之间的“T”分隔符可以通过协议省略,因此说它“不是 ISO 格式”并不完全正确。
0赞 Timothy Jones 11/15/2023
@RobG你有这方面的来源吗?
0赞 RobG 11/16/2023
国际标准化组织 8601。您可以购买它(CHF166)或在维基百科上查看摘要