我正在尝试测试以确保日期有效,因为如果有人输入2/30/2011
,那么它应该是错误的。
如何在任何日期执行此操作?
答案 0 :(得分:118)
验证日期字符串的一种简单方法是转换为日期对象并测试,例如
// 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))
})
答案 1 :(得分:10)
RobG提出的第一个函数isValidDate是否适用于输入字符串'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]);
}
答案 2 :(得分:5)
我建议使用moment.js。只提供日期到时间将验证它,不需要传递dateFormat。
var date = moment("2016-10-19");
然后date.isValid()
给出了期望的结果。
发表HERE
答案 3 :(得分:4)
此解决方案不涉及明显的日期验证,例如确保日期部分是整数,或者日期部分符合明显的验证检查,例如当天大于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,但可以使其更加强大。
答案 4 :(得分:4)
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值。例如:
if(isDate_(var_date)) {
// statements if the date is valid
} else {
// statements if not valid
}
答案 5 :(得分:1)
我只是翻拍RobG solution
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]
答案 6 :(得分:0)
这是JS6(带let声明)。
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的模型,您只需更改数组:
let months31 = [0,2,4,6,7,9,11];
let months30 = [3,5,8,10];
let months28 = [1];
如果您的日期格式为dd / mm / yyyy,则可以取消日,月和年功能参数,并执行此操作以检索它们:
let arrayWithDayMonthYear = myDateInString.split('/');
let year = parseInt(arrayWithDayMonthYear[2]);
let month = parseInt(arrayWithDayMonthYear[1]);
let day = parseInt(arrayWithDayMonthYear[0]);
答案 7 :(得分:0)
如果是有效日期,我的函数返回true,否则返回false:D
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));
&#13;
答案 8 :(得分:0)
不幸的是,JavaScript似乎没有简单的方法来验证日期字符串。这是我想到的在现代浏览器中解析日期格式为“ m / d / yyyy”的最简单方法(这就是为什么它不指定要解析的基数的原因,因为从ES5开始应该为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));
});
答案 9 :(得分:0)
嗨,请在下面找到答案。这是通过验证新创建的日期来完成的
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;
}
答案 10 :(得分:-1)
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));
}
答案 11 :(得分:-1)
虽然这很久以前就已经提出,但仍然是最需要验证的。我找到了一个有趣的blog功能很少。
/* 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;
}
将整个代码复制到一个文件中并包含。
希望这会有所帮助。