简体   繁体   English

为什么 moment(date).isValid() 返回错误的结果

[英]Why moment(date).isValid() returns wrong result

when I check the following date it returns true result, Why?当我检查以下日期时,它返回真实结果,为什么?

const value = "3";
if (moment(new Date(value), "DD-MM-YYYY HH:mm", true).isValid())  // true
{ }

or或者

const value = "3";
if (moment(new Date(value)).isValid())  // true
{ }

That is because new Date("3") is valid date and那是因为new Date("3")是有效日期并且

 console.log(new Date("3"))

This is one of those cases that shows you need to sanitize your date strings and should not depend on the native parser, unless you are sure your strings have already been validated and are conformant.这是表明您需要清理日期字符串并且不应依赖本机解析器的情况之一,除非您确定您的字符串已经过验证并且符合要求。

ECMA-262 Date(value) constructor specs ECMA-262 日期(值)构造函数规范
Date.parse日期解析

If the String does not conform to that format the function may fall back to any implementation-specific heuristics or implementation-specific date formats.如果字符串不符合该格式,则 function 可能会退回到任何特定于实现的启发式或特定于实现的日期格式。

So it's not conformant to "Date Time String Format" , which requires the string to start with "YYYY", so it goes to an implementation specific parsing that is similar to the rules for above, but using the form: "MM-DD-YYYY".所以它不符合"Date Time String Format" ,它要求字符串以 "YYYY" 开头,所以它会进行类似于上述规则的特定于实现的解析,但使用形式:"MM-DD- YYYY”。

The purpose of using strict mode (setting third argument of moment() to true) is to let moment do the string parsing and determine if it fits the formats that you provide (to for example avoid unexpected parsing behavior like this).使用严格模式(将 moment() 的第三个参数设置为 true)的目的是让 moment 进行字符串解析并确定它是否符合您提供的格式(例如避免像这样的意外解析行为)。 If you use Date() to parse, you are no longer using moment's strict mode to validate the string fits your required format.如果您使用 Date() 进行解析,则不再使用 moment 的严格模式来验证字符串是否符合您所需的格式。

 let value = "3"; function checkDate(value){ console.log(value, moment(value, "DD-MM-YYYY HH:mm", true).isValid()? 'valid': 'invalid') } value = "01-01-2011 11:22" checkDate(value) value = "01-01-2011 11:22Z" checkDate(value) value = "3" checkDate(value) value = new Date("3").toString() checkDate(value) value = new Date('INVALID DATE') checkDate(value)
 <script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.25.3/moment-with-locales.min.js" integrity="sha256-8d6kI5cQEwofkZmaPTRbKgyD70GN5mDpTYNP9YWhTlI=" crossorigin="anonymous"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/moment-timezone/0.5.28/moment-timezone-with-data.js" integrity="sha256-O1PdKrSbpAYWSBteb7yX/CMmHhu3US31mtCbsryGwaY=" crossorigin="anonymous"></script>

If you don't need to validate the date string (for example to prevent unexpected parsing behavior), don't need to worry about non-modern browsers, and really just need to parse conforming Date strings and format to basic string formats, you could just use native Date() with Intl.DateTimeFormat or Date.prototype.toLocaleString .如果您不需要验证日期字符串(例如为了防止意外的解析行为),不需要担心非现代浏览器,并且真的只需要将符合的日期字符串和格式解析为基本字符串格式,您可以将本机Date()Intl.DateTimeFormatDate.prototype.toLocaleString 一起使用
TL;DR the way you are using it right now implies that you don't actually need moment TL;DR 您现在使用它的方式意味着您实际上并不需要时间

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM