【问题标题】:Why can i parse invalid date string? [duplicate]为什么我可以解析无效的日期字符串? [复制]
【发布时间】:2020-02-24 21:13:30
【问题描述】:

我使用一个函数来检查输入的值是否是在我的应用程序中用于特定目的的有效文本。

有效值是一个字符串,它不是有效的日期或数字,既不是真也不是假。

checkText(str) {
    return isNaN(str) && isNaN(Date.parse(str)) && ['true', 'false'].indexOf(str) == -1;
} 

它工作正常,但我遇到了这个字符串的问题:“New Item 3”。

Date.parse("New Item 3") 返回一个数字,但是为什么呢!!?另外,如果您将 3 更改为小于 13 的任何数字,它将返回数字!

这里的任何人都可以向我解释会发生什么?

【问题讨论】:

  • 无论前面有多少个字符串,它都会返回一个数字。例如。 Date.parse("New Item Blah Foo 3")Date.parse("N 3") 也将被正确解析。我猜字符串中的最后一个数字被解释为一个月,这就是为什么它在大于 12 时返回 NaN。我在最新版本的 Brave、Chromium 和 Chrome 上对其进行了测试(它们都使用 V8)。
  • 非标准日期字符串的处理依赖于平台。也许无论您在何种环境中尝试过,都会以某种方式发现这是一个非无效字符串,并使用一些奇怪的规则对其进行解析。例如,它在 Firefox 中不起作用。
  • Date.parse("New Item 3") 在 FF70 中返回 NaN。不过,typeof NaN 是“数字”。
  • 有趣的是,在 Firefox 和 IE11 中 Date.parse("New Item 3") 返回 NaN,在 Chrome/Chromium 中返回 983401200000
  • 来自 MDN:“在 ES5 之前不建议使用 Date.parse,字符串的解析完全取决于实现。不同主机解析日期字符串的方式仍有很多差异,因此日期字符串应该手动解析(如果要容纳许多不同的格式,库可以提供帮助)。”

标签: javascript string date nan


【解决方案1】:

经验教训:Date.parse 不是日期验证器。

甚至 MDN says:

不建议使用Date.parse,因为在 ES5 之前,字符串的解析完全依赖于实现。不同主机解析日期字符串的方式仍有很多差异,因此应手动解析日期字符串(如果要适应许多不同的格式,库可以提供帮助)。

再往下

ECMAScript 规范规定:如果字符串不符合标准格式,则函数可能会退回到任何特定于实现的启发式算法或特定于实现的解析算法。无法识别的字符串或包含 ISO 格式字符串中非法元素值的日期应导致 Date.parse() 返回 NaN。

但是,日期字符串中的无效值不被识别为 ECMA-262 定义的简化 ISO 格式可能会也可能不会导致 NaN,具体取决于浏览器和提供的值

【讨论】:

  • "经验教训:Date.parse 不是日期验证器。" 实际上,它是一个日期解析器。此外,它更像letMyCurrentEnvironmentTryToParseThisStringUsingSomeAdditionalNonStandardAndLegacyRulesThatAreProbablyNotWellDocumentedIfAtAll 虽然我猜这个名字可能有点太长了,即使是描述性的。
【解决方案2】:

事实上这里的问题来自Date.parse() method,如果你检查一下:

Date.parse("New Item 3");

它会返回:

983401200000

console.log(Date.parse("New Item 3"));

所以这里的事实是Date.parse() 将根据浏览器规范运行,可能会或不会返回Number取决于浏览器

您可以从Date.parse() MDN reference 看到:

ECMAScript 规范规定:如果字符串不符合标准格式,则函数可能会退回到任何特定于实现的启发式算法或特定于实现的解析算法。无法识别的字符串或包含 ISO 格式字符串中非法元素值的日期应导致 Date.parse() 返回 NaN。

但是,日期字符串中的无效值不会被识别为简化 ECMA-262 定义的 ISO 格式可能会或可能不会导致 NaN, 取决于提供的浏览器和值。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-05-28
    • 1970-01-01
    • 2021-10-12
    • 1970-01-01
    • 2023-03-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多