为什么年份返回为NaN?

时间:2018-08-06 16:09:54

标签: javascript momentjs

我正在尝试验证日期,规则如下:

  • 非leap年或无效日期
  • 年份必须大于1868

我正在使用momentjs进行这种验证,这就是我的操作方式:

function validate() {
  var value = moment('33/33/1986', 'MM/DD/YYYY');
  var year = moment('33/33/1986', 'MM/DD/YYYY').year();

  console.log(value)
  console.log(year)

  if (value.isValid() && year >= 1868) {
    return true;
  }
}
validate();
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.22.2/moment.js"></script>

为什么year包含一个NaN值?是的,我知道日期无效,并且moment().isValid()将返回false,但是即使不是假设我应该获得正确的year值,也是如此?

  

注意:该代码段不会打印存储在value中的momentjs对象   改用this fiddle

如果有任何机会您知道一种更好的方法来进行相同的验证,请随时在此处发布!

5 个答案:

答案 0 :(得分:2)

33/33/1986不是Momentjs有效对象,因为日期和月份无效。

您应该尝试使用正确的日期和月份,例如12/12/1986

答案 1 :(得分:2)

MomentJS在对提供格式的moment()的任何调用中提供parsingFlags。您可以使用它来猜测年份。

parsingFlags包含一个parsedDateParts数组,该数组包含按降序分析的值,第一个值为年,第二个为月,等等。

很明显,如果有人输入了无效的年份,那么所有赌注都关闭了...

以下代码显示了所有parsingFlags,然后输出在parsedDateParts中找到的年份。

function validate() {
  var value = moment('33/33/1986', 'MM/DD/YYYY');
  var year = moment('33/33/1986', 'MM/DD/YYYY').parsingFlags().parsedDateParts[0];

  console.log(moment('33/33/1986', 'MM/DD/YYYY').parsingFlags())
  console.log(year)

  if (value.isValid() && year >= 1868) {
    return true;
  }
}
validate();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.22.2/moment.js"></script>

答案 2 :(得分:1)

  • 为什么年份包含NaN值?

由于moment('33/33/1986', 'MM/DD/YYYY').isValid()false,因此文档的时刻Validation部分明确指出:

  

如果力矩无效,则在浮点运算中的行为类似于NaN。

     

...

     

这些返回具有某些结构的null或NaN:

     
      
  • invalid.get(unit)返回null,就像其他所有命名的getter一样
  •   
  • 如果有机会您知道一种更好的方法来进行相同的验证,请随时在此处发布!

您可以使用strict mode(在解析输入时添加true作为第三个参数)来改善验证,如以下代码段所示:

function validate(input) {
  var value = moment(input, 'MM/DD/YYYY', true);
  var year = value.year();

  if (value.isValid() && year >= 1868) {
    return true;
  }
  return false;
}
console.log( validate('33/33/1986') );
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.22.2/moment.js"></script>

请注意,您可以使用isLeapYear()函数:

  

moment#isLeapYear如果年份是a年则返回true,如果不是a年则返回false

如果您必须按照问题第一部分所述排除非leap年

答案 3 :(得分:0)

您不能解析不存在的日期。没有第33天或第33个月。如果您使用有效日期,则代码将正常运行。

答案 4 :(得分:0)

第一个moment不喜欢为您解析没有指定格式的日期,也不喜欢完全解析错误的日期(我们只有12个月,最多31天,所以33/33/是什么? )。

尝试一下:

var year = moment('12/20/1986', 'MM/DD/YYYY').year();

if (year >= 1868) {
  console.log('YAY!')
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.22.2/moment.min.js"></script>