【问题标题】:javascript date validation not validation February 31javascript 日期验证不验证 2 月 31 日
【发布时间】:2014-01-17 14:36:38
【问题描述】:

我正在尝试编写一些代码来验证表单数据。我有一个日期字段,它应该具有mm/dd/yyyy 格式。我需要捕获2 月 31 日 等异常,所以我添加了以下代码:

var d = new Date(dob);
if (isNaN(d.getTime())) { //this if is to take care of February 31, BUT IT DOESN'T!
  error = 1;
  message += "<li>Invalid Date</li>";
} else {
  var date_regex = /^(0[1-9]|1[0-2])\/(0[1-9]|1\d|2\d|3[01])\/(19|20)\d{2}$/;
  var validFormat = date_regex.test(dob);
  if (!(validFormat)) {
    error = 1;
    message += "<li>Invalid date format - date must have format mm/dd/yyyy</li>";
  }
}

但是我发现了一些非常奇怪的事情:虽然日期 02/32/2000 错误为无效日期,但 02/31/2000 不会!

【问题讨论】:

  • new Date('2013-02-31 00:00:00') 实际上计算为 Sun Mar 03 2013 00:00:00 GMT-0500 (Eastern Standard Time) 所以这就是它不会出错的原因。虽然不是 100% 确定原因
  • 这将发生在每个月少于 31 天...

标签: javascript validation


【解决方案1】:

由于我在 cmets 中所说的...

您可以检查日期是否有效的另一种方法是检查您传递给new Date 函数的内容是否与它输出的内容相同,如下所示:

// Remember that the month is 0-based so February is actually 1...
function isValidDate(year, month, day) {
    var d = new Date(year, month, day);
    if (d.getFullYear() == year && d.getMonth() == month && d.getDate() == day) {
        return true;
    }
    return false;
}

那么你可以这样做:

if (isValidDate(2013,1,31))

如果有效则返回true,如果无效则返回false

【讨论】:

  • 很好,只需将== date 更改为== day
  • 真的很好!也可以是return d.getFullYear() == year &amp;&amp; d.getMonth() == month &amp;&amp; d.getDate() == day
  • 此方法不适合消耗品Date 构造函数中月份的 0-indexed 性质只是一个很大的设计缺陷 (stackoverflow.com/q/2552483/2561091)。我浪费了时间,因为没有注意对您方法的评论,并且没有意识到月份参数应该是0-indexed。我重新编写了该方法,因为它使新答案更具可读性(并且略显现代)。
  • 我喜欢这样优雅的答案
【解决方案2】:

Date.getMonth()(以及.getDay() 的工作日)被0-index(尽管年、日和所有其他人都不是这样......哦上帝...... .) 我重新编写了 Jeff 的答案,以使其更具可读性和更友好 - 可供从外部使用该方法的人使用。

ES6 代码

您可以按照您通常的预期将过去的月份称为1-indexed

我已使用 Number constructor 解析输入,因此我可以使用 strict equality 更自信地比较值。

我使用UTC 版本方法来避免处理本地时区。

此外,为了便于阅读,我将步骤分解为一些变量。

/**
 *
 * @param { number | string } day
 * @param { number | string } month
 * @param { number| string } year
 * @returns { boolean }
 */
function validateDateString(day, month, year) {

    day = Number(day);
    month = Number(month) - 1; //bloody 0-indexed month
    year = Number(year);

    let d = new Date(year, month, day);

    let yearMatches = d.getUTCFullYear() === year;
    let monthMatches = d.getUTCMonth() === month;
    let dayMatches = d.getUTCDate() === day;

    return yearMatches && monthMatches && dayMatches;
}

【讨论】:

  • 不应该是month = Number(month) + 1,因为它是 0 索引意味着一月 = 0,而它应该是 = 1?您的代码似乎会说一月是-1,十二月是 10
  • 嗨@RyanRussell,我的方法是Number(month) -1,因为我的界面validateDateString 正在简化使用1-index 月份的心理过程。对于一月份,您将使用我的函数传递1 作为参数,并在内部将其减去以符合Date 的混乱界面。
【解决方案3】:

你可以使用图书馆吗?

我在 Javascript 中处理日期的第一个调用端口是 moment.js:“用于解析、验证、操作和格式化日期的 javascript 日期库。”

【讨论】:

    【解决方案4】:

    验证“mm/dd/yyyy”日期字符串的常用方法是创建一个日期对象并验证其月份和日期是否与输入相同。

    function isvalid_mdy(s){
        var day, A= s.match(/[1-9][\d]*/g);
        try{
            A[0]-= 1;
            day= new Date(+A[2], A[0], +A[1]);
            if(day.getMonth()== A[0] && day.getDate()== A[1]) return day;
            throw new Error('Bad Date ');
        }
        catch(er){
            return er.message;
        }
    }
    

    isvalid_mdy('02/31/2000')

    /* 返回值:(Error)Bad Date */

    【讨论】:

      【解决方案5】:

      基本上是上述例子的替代方案

      function (date) {
      
          if (!/(0[1-9]|1[0-9]|2[0-9]|3[0-1])\/(0[1-9]|1[0-2])\/([1-2][0-9]{3})/g.test(date))
          {
              alert('Incorrect date format please follow this form: dd/mm/yyyy');
              return;
          }
          else
          {
              // secondary validation
              const parts = (date).split('/').map((p) => parseInt(p, 10));
              let day = Number(parts[0]);
              let month = Number(parts[1]) - 1; // 0-indexed month
              let year = Number(parts[2]);
              let d = new Date(year, month, day);
              if (!(d.getFullYear() == year && d.getMonth() == month && d.getDate() == day))
              {
                  alert('Incorrect date, please enter the correct day entry');
                  return;
              }
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-02-23
        • 1970-01-01
        • 1970-01-01
        • 2023-03-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多