如何验证日期?

IT技术 javascript validation
2021-01-29 18:25:47

我正在尝试测试以确保日期有效,因为如果有人进入,2/30/2011那么它应该是错误的。

我怎么能用任何日期做到这一点?

6个回答

验证日期字符串的一种简单方法是转换为日期对象并进行测试,例如

// Expect input as d/m/y
function isValidDate(s) {
  var bits = s.split('/');
  var d = new Date(bits[2], bits[1] - 1, bits[0]);
  return d && (d.getMonth() + 1) == bits[1];
}

['0/10/2017','29/2/2016','01/02'].forEach(function(s) {
  console.log(s + ' : ' + isValidDate(s))
})

以这种方式测试日期时,只需要测试月份,因为如果日期超出范围,月份就会改变。如果月份超出范围,则相同。任何年份都有效。

您还可以测试日期字符串的位:

function isValidDate2(s) {
  var bits = s.split('/');
  var y = bits[2],
    m = bits[1],
    d = bits[0];
  // Assume not leap year by default (note zero index for Jan)
  var daysInMonth = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];

  // If evenly divisible by 4 and not evenly divisible by 100,
  // or is evenly divisible by 400, then a leap year
  if ((!(y % 4) && y % 100) || !(y % 400)) {
    daysInMonth[1] = 29;
  }
  return !(/\D/.test(String(d))) && d > 0 && d <= daysInMonth[--m]
}

['0/10/2017','29/2/2016','01/02'].forEach(function(s) {
  console.log(s + ' : ' + isValidDate2(s))
})

注意:用于示例 2 的日期格式是 dd/mm/yyyy 而不是 mm/dd/yyyy
2021-03-12 18:25:47
方法 2 不会将 00/10/2000 标记为有效日期吗?
2021-03-16 18:25:47
@DanielScocco——绝对正确!已修复,并转换为可运行的代码段。;-)
2021-03-22 18:25:47
提出的第一个解决方案并不真正完整。例如,它为“367/1/2000”返回 true,但它实际上不是一个有效日期。看看我的答案,其中包括在解析日期和比较月份之前进行的正则表达式检查。
2021-03-30 18:25:47

RobG 提出的第一个函数 isValidDate(s) 是否适用于输入字符串“1/2/”?我认为不是,因为 YEAR 未经过验证;(

我的提议是使用这个函数的改进版本:

//input in ISO format: yyyy-MM-dd
function DatePicker_IsValidDate(input) {
        var bits = input.split('-');
        var d = new Date(bits[0], bits[1] - 1, bits[2]);
        return d.getFullYear() == bits[0] && (d.getMonth() + 1) == bits[1] && d.getDate() == Number(bits[2]);
}
@adi518—在两个示例中都添加了“01/02”作为测试,第一个返回 false,第二个返回 true。如果他们想改变与否,我会把它留给其他人。
2021-03-13 18:25:47
@KevinFegan-如果是这样,那么结果将是无效日期,并且月份检查将(正确)失败。;-)
2021-03-15 18:25:47
罗伯,我注意到尝试你的解决方案01/02返回 true。
2021-03-31 18:25:47
@RobG - 我认为 Piotr 的观点是应该检查年份,以防“年份”是null或不是数字。
2021-04-07 18:25:47
你应该不这么想,我发布的功能只需要检查月份。检查更多是多余的,因为如果日期或月份超出范围,月份就会改变。测试年份没有实际意义,因为任何年份可能有效也可能无效,并且只有当月份也发生变化时,它的值才会发生变化。
2021-04-09 18:25:47

我推荐使用moment.js。只提供日期到时刻会验证它,不需要传递日期格式。

var date = moment("2016-10-19");

然后date.isValid()给出想要的结果。

这里发帖

Moment 是一个很棒的库,我实际上将它用于我当前的大多数 Web 项目,但是我最初试图在没有任何其他库的情况下实现这一点。感谢您的贡献,我强烈推荐 Moment.js
2021-03-17 18:25:47
关于“无需传递 dateFormat ”,您应该始终传递格式。如果它不是默认的 moment.js 格式,它会回退到内置解析器,因此不会比new Date(string).
2021-03-20 18:25:47
这仅适用于日期格式为“RFC2822 或 ISO”格式的情况。否则,它会传递给原始的 Date 构造函数。所以它不会解决 op 的问题:moment('2/30/2011').isValid()返回true
2021-04-01 18:25:47

此解决方案不解决明显的日期验证问题,例如确保日期部分是整数或日期部分符合明显的验证检查,例如日期大于 0 且小于 32。此解决方案假定您已经拥有所有三个日期部分(年、月、日)并且每个都已经通过了明显的验证。鉴于这些假设,此方法应该可以用于简单地检查日期是否存在。

例如,2009 年 2 月 29 日不是实际日期,但 2008 年 2 月 29 日是。当你创建一个新的 Date 对象时,比如 2009 年 2 月 29 日,看看会发生什么(记住在 JavaScript 中月份是从零开始的):

console.log(new Date(2009, 1, 29));

以上行输出:Sun Mar 01 2009 00:00:00 GMT-0800 (PST)

请注意日期如何简单地滚动到下个月的第一天。假设您有其他明显的验证,此信息可用于通过以下函数确定日期是否真实(此函数允许基于非零的月份以便更方便地输入):

var isActualDate = function (month, day, year) {
    var tempDate = new Date(year, --month, day);
    return month === tempDate.getMonth();
};

这不是一个完整的解决方案,也没有考虑 i18n,但它可以变得更加健壮。

var isDate_ = function(input) {
        var status = false;
        if (!input || input.length <= 0) {
          status = false;
        } else {
          var result = new Date(input);
          if (result == 'Invalid Date') {
            status = false;
          } else {
            status = true;
          }
        }
        return status;
      }

此函数返回给定的输入是否为有效日期的布尔值。前任:

if(isDate_(var_date)) {
  // statements if the date is valid
} else {
  // statements if not valid
}
请评论您的代码段 - 它如何帮助 OP
2021-03-11 18:25:47
它不适用于所有日期格式。前任。dd-MMM-yyyy
2021-03-11 18:25:47
'Invalid Date'是类型检查。如果与字符串相比,结果不会为真。
2021-03-14 18:25:47
你有变化 -->7.line (result.toString() === 'Invalid Date')
2021-04-03 18:25:47