关于javascript:如何验证日期?

How to validate a date?

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

我怎么能在任何日期这样做?


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

1
2
3
4
5
6
7
8
9
10
// 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))
})

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

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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))
})


RobG提出的第一个函数isValidDate是否适用于输入字符串'1/2 /'?
我想不是,因为YEAR没有经过验证;(

我的主张是使用此功能的改进版本:

1
2
3
4
5
6
//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]);
}


我建议使用moment.js。只提供日期到时间将验证它,不需要传递dateFormat。

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

然后date.isValid()给出所需的结果。

Se发布在这里


1
2
3
4
5
6
7
8
9
10
11
12
13
14
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;
      }

此函数返回给定输入是否为有效日期的bool值。例如:

1
2
3
4
5
if(isDate_(var_date)) {
  // statements if the date is valid
} else {
  // statements if not valid
}


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

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

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

以上产品线:Sun Mar 01 2009 00:00:00 GMT-0800(太平洋标准时间)

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

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

这不是一个完整的解决方案,也不考虑i18n,但可以使其更加强大。


这是JS6(带let声明)。

1
2
3
4
5
6
7
8
9
10
11
12
function checkExistingDate(year, month, day){ // year, month and day should be numbers
     // months are intended from 1 to 12
    let months31 = [1,3,5,7,8,10,12]; // months with 31 days
    let months30 = [4,6,9,11]; // months with 30 days
    let months28 = [2]; // the only month with 28 days (29 if year isLeap)

    let isLeap = ((year % 4 === 0) && (year % 100 !== 0)) || (year % 400 === 0);

    let valid = (months31.indexOf(month)!==-1 && day <= 31) || (months30.indexOf(month)!==-1 && day <= 30) || (months28.indexOf(month)!==-1 && day <= 28) || (months28.indexOf(month)!==-1 && day <= 29 && isLeap);

    return valid; // it returns true or false
}

在这种情况下,我打算从1到12的几个月。如果您更喜欢或使用基于0-11的模型,您只需更改数组:

1
2
3
let months31 = [0,2,4,6,7,9,11];
let months30 = [3,5,8,10];
let months28 = [1];

如果您的日期格式为dd / mm / yyyy,则可以取消日,月和年函数参数,并执行此操作以检索它们:

1
2
3
4
let arrayWithDayMonthYear = myDateInString.split('/');
let year = parseInt(arrayWithDayMonthYear[2]);
let month  = parseInt(arrayWithDayMonthYear[1]);
let day = parseInt(arrayWithDayMonthYear[0]);


我只是重拍了RobG解决方案

1
2
3
4
5
6
7
var daysInMonth = [31,28,31,30,31,30,31,31,30,31,30,31];
var isLeap = new Date(theYear,1,29).getDate() == 29;

if (isLeap) {
  daysInMonth[1] = 29;
}
return theDay <= daysInMonth[--theMonth]

嗨请在下面找到答案。这是通过验证新创建的日期来完成的

1
2
3
4
5
6
7
8
9
10
var year=2019;
var month=2;
var date=31;
var d = new Date(year, month - 1, date);
if (d.getFullYear() != year
        || d.getMonth() != (month - 1)
        || d.getDate() != date) {
    alert("invalid date");
    return false;
}

不幸的是,似乎JavaScript没有简单的方法来验证日期字符串。这是我能想到的在现代浏览器中以"m / d / yyyy"格式解析日期的最简单方法(这就是为什么它没有指定parseInt的基数,因为它自ES5起应该是10):

1
2
3
4
5
6
7
8
9
10
const dateValidationRegex = /^\d{1,2}\/\d{1,2}\/\d{4}$/;
function isValidDate(strDate) {
  if (!dateValidationRegex.test(strDate)) return false;
  const [m, d, y] = strDate.split('/').map(n => parseInt(n));
  return m === new Date(y, m - 1, d).getMonth() + 1;
}

['10/30/2000abc', '10/30/2000', '1/1/1900', '02/30/2000', '1/1/1/4'].forEach(d => {
  console.log(d, isValidDate(d));
});


如果是有效日期,我的函数返回true,否则返回false:D

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
function isDate  (day, month, year){
    if(day == 0 ){
        return false;
    }
    switch(month){
        case 1: case 3: case 5: case 7: case 8: case 10: case 12:
            if(day > 31)
                return false;
            return true;
        case 2:
            if (year % 4 == 0)
                if(day > 29){
                    return false;
                }
                else{
                    return true;
                }
            if(day > 28){
                return false;
            }
            return true;
        case 4: case 6: case 9: case 11:
            if(day > 30){
                return false;
            }
            return true;
        default:
            return false;
    }
}

console.log(isDate(30, 5, 2017));
console.log(isDate(29, 2, 2016));
console.log(isDate(29, 2, 2015));


虽然这很久以前就已经提出,但仍然是最需要验证的。我找到了一个功能很少的有趣博客。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
/* Please use these function to check the reuslt only. do not check for otherewise. other than utiljs_isInvalidDate

Ex:-

utiljs_isFutureDate() retuns only true for future dates. false does not mean it is not future date. it may be an invalid date.

practice :

call utiljs_isInvalidDate first and then use the returned date for utiljs_isFutureDate()

var d = {};

if(!utiljs_isInvalidDate('32/02/2012', d))

if(utiljs_isFutureDate(d))

//date is a future date

else

// date is not a future date



 */


function utiljs_isInvalidDate(dateStr, returnDate) {

    /*dateStr | format should be dd/mm/yyyy, Ex:- 31/10/2017

     *returnDate will be in {date:js date object}.

     *Ex:- if you only need to check whether the date is invalid,

     * utiljs_isInvalidDate('03/03/2017')

     *Ex:- if need the date, if the date is valid,

     * var dt = {};

     * if(!utiljs_isInvalidDate('03/03/2017', dt)){

     *  //you can use dt.date

     * }

     */


    if (!dateStr)
        return true;
    if (!dateStr.substring || !dateStr.length || dateStr.length != 10)
        return true;
    var day = parseInt(dateStr.substring(0, 2), 10);
    var month = parseInt(dateStr.substring(3, 5), 10);
    var year = parseInt(dateStr.substring(6), 10);
    var fullString = dateStr.substring(0, 2) + dateStr.substring(3, 5) + dateStr.substring(6);
    if (null == fullString.match(/^\d+$/)) //to check for whether there are only numbers
        return true;
    var dt = new Date(month +"/" + day +"/" + year);
    if (dt == 'Invalid Date' || isNaN(dt)) { //if the date string is not valid, new Date will create this string instead
        return true;
    }
    if (dt.getFullYear() != year || dt.getMonth() + 1 != month || dt.getDate() != day) //to avoid 31/02/2018 like dates
        return true;
    if (returnDate)
        returnDate.date = dt;
    return false;
}

function utiljs_isFutureDate(dateStrOrObject, returnDate) {
    return utiljs_isFuturePast(dateStrOrObject, returnDate, true);
}

function utiljs_isPastDate(dateStrOrObject, returnDate) {
    return utiljs_isFuturePast(dateStrOrObject, returnDate, false);
}

function utiljs_isValidDateObjectOrDateString(dateStrOrObject, returnDate) { //this is an internal function
    var dt = {};
    if (!dateStrOrObject)
        return false;
    if (typeof dateStrOrObject.getMonth === 'function')
        dt.date = new Date(dateStrOrObject); //to avoid modifying original date
    else if (utiljs_isInvalidDate(dateStrOrObject, dt))
        return false;
    if (returnDate)
        returnDate.date = dt.date;
    return true;

}

function utiljs_isFuturePast(dateStrOrObject, returnDate, isFuture) { //this is an internal function, please use isFutureDate or isPastDate function
    if (!dateStrOrObject)
        return false;
    var dt = {};
    if (!utiljs_isValidDateObjectOrDateString(dateStrOrObject, dt))
        return false;
    today = new Date();
    today.setHours(0, 0, 0, 0);
    if (dt.date)
        dt.date.setHours(0, 0, 0, 0);
    if (returnDate)
        returnDate.date = dt.date;
    //creating new date using only current d/m/y. as td.date is created with string. otherwise same day selection will not be validated.
    if (isFuture && dt.date && dt.date.getTime && dt.date.getTime() > today.getTime()) {
        return true;
    }
    if (!isFuture && dt.date && dt.date.getTime && dt.date.getTime() < today.getTime()) {
        return true;
    }
    return false;
}

function utiljs_isLeapYear(dateStrOrObject, returnDate) {
    var dt = {};
    if (!dateStrOrObject)
        return false;
    if (utiljs_isValidDateObjectOrDateString(dateStrOrObject, dt)) {
        if (returnDate)
            returnDate.date = dt.date;
        return dt.date.getFullYear() % 4 == 0;
    }
    return false;
}

function utiljs_firstDateLaterThanSecond(firstDate, secondDate, returnFirstDate, returnSecondDate) {
    if (!firstDate || !secondDate)
        return false;
    var dt1 = {},
    dt2 = {};
    if (!utiljs_isValidDateObjectOrDateString(firstDate, dt1) || !utiljs_isValidDateObjectOrDateString(secondDate, dt2))
        return false;
    if (returnFirstDate)
        returnFirstDate.date = dt1.date;
    if (returnSecondDate)
        returnSecondDate.date = dt2.date;
    dt1.date.setHours(0, 0, 0, 0);
    dt2.date.setHours(0, 0, 0, 0);
    if (dt1.date.getTime && dt2.date.getTime && dt1.date.getTime() > dt2.date.getTime())
        return true;
    return false;
}

function utiljs_isEqual(firstDate, secondDate, returnFirstDate, returnSecondDate) {
    if (!firstDate || !secondDate)
        return false;
    var dt1 = {},
    dt2 = {};
    if (!utiljs_isValidDateObjectOrDateString(firstDate, dt1) || !utiljs_isValidDateObjectOrDateString(secondDate, dt2))
        return false;
    if (returnFirstDate)
        returnFirstDate.date = dt1.date;
    if (returnSecondDate)
        returnSecondDate.date = dt2.date;
    dt1.date.setHours(0, 0, 0, 0);
    dt2.date.setHours(0, 0, 0, 0);
    if (dt1.date.getTime && dt2.date.getTime && dt1.date.getTime() == dt2.date.getTime())
        return true;
    return false;
}

function utiljs_firstDateEarlierThanSecond(firstDate, secondDate, returnFirstDate, returnSecondDate) {
    if (!firstDate || !secondDate)
        return false;
    var dt1 = {},
    dt2 = {};
    if (!utiljs_isValidDateObjectOrDateString(firstDate, dt1) || !utiljs_isValidDateObjectOrDateString(secondDate, dt2))
        return false;
    if (returnFirstDate)
        returnFirstDate.date = dt1.date;
    if (returnSecondDate)
        returnSecondDate.date = dt2.date;
    dt1.date.setHours(0, 0, 0, 0);
    dt2.date.setHours(0, 0, 0, 0);
    if (dt1.date.getTime && dt2.date.getTime && dt1.date.getTime() < dt2.date.getTime())
        return true;
    return false;
}

将整个代码复制到一个文件中并包含。

希望这可以帮助。


1
2
3
4
function isValidDate(year, month, day) {
        var d = new Date(year, month - 1, day, 0, 0, 0, 0);
        return (!isNaN(d) && (d.getDate() == day && d.getMonth() + 1 == month && d.getYear() == year));
    }