【问题标题】:moment.js date validation from array of formats来自格式数组的 moment.js 日期验证
【发布时间】:2017-06-16 09:31:18
【问题描述】:

我需要测试输入的正确日期格式。我想接受几种日期格式,所以我创建了一个验证函数来测试至少一种格式是否正常,在这种情况下返回 true。 我使用 moment.js 来测试日期。 当我简单地使用硬编码字符串日期格式键入条件时,该函数可以正常工作:

var multiDateValidator = function (value)
{
    if ((moment(value, 'DD/MM/YYYY', true).isValid()) ||
        (moment(value, 'D/M/YYYY', true).isValid()) ||
        (moment(value, 'DD.MM.YYYY', true).isValid()) ||
        (moment(value, 'D.M.YYYY', true).isValid()) ||
        (moment(value, 'DD. MM. YYYY', true).isValid()) ||
        (moment(value, 'D. M. YYYY', true).isValid())) {
        return true;
    }

    return false;
};

但如果我想使用允许的日期格式列表,它不起作用,它永远不会返回 true。

var allowedDateFormats = ['DD/MM/YYYY', 'D/M/YYYY', 'DD.MM.YYYY', 'D.M.YYYY', 'DD. MM. YYYY', 'D. M. YYYY'];

var multiDateValidator = function (value)
{
    allowedDateFormats.forEach(function(dateFormat)
    {
        if (moment(value, dateFormat, true).isValid()) {
            return true;
        }
    });

    return false;
};

第二个函数有什么问题?我知道我不太擅长 JavaScript,但它应该可以工作,不是吗?

【问题讨论】:

  • 范围。代码中有 2 个函数。 return true 在第二个里面,return false 在第一个里面。如果你在return true 上面加上console.log("some text");,你就会明白我的意思了。
  • 你说得对,我不能使用 .forEach(),我必须使用 for...of。您可以发表您的评论作为我可以确认的答案吗?谢谢
  • 我已经发布了我的评论作为一个非常懒惰的解决方案的答案,仍然有效
  • **已编辑的答案,目前使用

标签: javascript momentjs


【解决方案1】:

无需使用forforEach 循环。 Moment 提供moment(String, String[], String, Boolean); 多种格式解析字符串的方法。

正如文档所说:

如果您不知道输入字符串的确切格式,但知道它可能是众多格式之一,则可以使用格式数组。

2.3.0 版本开始,Moment 使用一些简单的启发式方法来确定要使用的格式。顺序:

  • 优先使用导致valid 日期的格式而不是无效的日期。
  • 更喜欢解析更多字符串而不是更少并且使用更多格式而不是更少的格式,即更喜欢更严格的解析。
  • 首选数组中较早的格式。

这是一个工作现场样本:

var allowedDateFormats = ['DD/MM/YYYY', 'D/M/YYYY', 'DD.MM.YYYY', 'D.M.YYYY', 'DD. MM. YYYY', 'D. M. YYYY'];

var multiDateValidator = function (value){
  return moment(value, allowedDateFormats, true).isValid();
};

var test = ['01/01/2017', '01.01.2017', '2017-Jan-01'];
for(var i=0; i<test.length; i++){
  console.log(test[i], multiDateValidator(test[i]));
}
&lt;script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.18.1/moment.min.js"&gt;&lt;/script&gt;

【讨论】:

    【解决方案2】:

    正如我在评论中提到的,return true 返回到内部函数,但它不会阻止外部函数执行,因此您的外部函数每次都会执行(即每次执行 return false 时)

    我的解决方案是:

    var allowedDateFormats = ['DD/MM/YYYY', 'D/M/YYYY', 'DD.MM.YYYY', 'D.M.YYYY', 'DD. MM. YYYY', 'D. M. YYYY'];
    
    var multiDateValidator = function (value)
    {  
      for(var dateFormat of allowedDateFormats) {
        if (moment(value, dateFormat, true).isValid()) {
          return true;
        }
      }  
      return false;
    };
    

    【讨论】:

    • 即使我后来将接受的答案更改为 VincenzoC 的答案,您对我函数中作用域的解释对我来说非常有用。谢谢。
    • 当然!我经常使用 momentjs,但不知道你可以在没有循环的情况下做到这一点!不错!
    猜你喜欢
    • 1970-01-01
    • 2015-07-19
    • 1970-01-01
    • 1970-01-01
    • 2018-03-17
    • 1970-01-01
    • 2017-04-04
    • 2014-02-13
    • 1970-01-01
    相关资源
    最近更新 更多