JavaScript日期验证(DD/MM/YYYY)和年龄检查

12

我最近开始学习JavaScript。我正在测试的是验证日期格式的出生日期。下一步将是检查年龄。

我的HTML代码包括如下内容:

<form name="ProcessInfo" action="#" method="POST" enctype="multipart/form-data" target="_self" onsubmit="return checkForm();">
.
.
.
.
<br>
<label for="txtDOB">Date of Birth:* </label>
<input id="txtDOB" type="text" name="txtDOB" size="12">
format: ##/##/####
<br>
.
.
.
</form>
.
.

然后我在我的.js文件中执行了以下操作

var errMessage = "";

function checkForm() {
    validateName();
    validateSurname();
    carSelect();
    validateDOB();

    if (errMessage == "") {
    } else {
        alert(errMessage);
    }
}

...

function validateDOB()
{
    var dob = document.forms["ProcessInfo"]["txtDOB"].value;
    var pattern = /^([0-9]{2})-([0-9]{2})-([0-9]{4})$/;
    if (dob == null || dob == "" || !pattern.test(dob)) {
        errMessage += "Invalid date of birth\n";
        return false;
    }
    else {
        return true
    }
}

我尝试使用正则表达式来检查日期的有效性,但即使我输入正确的日期也会收到警报。另外,我该如何分离出日/月/年以计算年龄?


你的模式使用破折号(-)分隔,而不是斜杠(/)。你实际上想要哪一个?此外,你可以使用\d作为[0-9]的等效表示。 - Ingo Bürk
谢谢提醒!我想使用 /,但当我将 - 更改为 / 时出现错误。我以为我在使用 /^ - A. Mesut Konuklar
99/99/9999是一个有效的日期吗? - BalusC
@BalusC 没有必要花费大量精力来禁止 99/99/9999。如果用户想撒谎,他仍然可以输入一个有效但不正确的日期。这样的验证只应用于拼写错误的情况下提供反馈。 - Ingo Bürk
1
@Ingo:只是想提供一些思路;) 顺便说一句,\d应该在除了JS之外的其他语言中小心使用,例如Java/C#。它也匹配非拉丁数字,如希伯来语,中文,波斯语等。 - BalusC
好的。 :) @user1700286 请记住,如果需要超过简单用户反馈,客户端验证是无用的。例如,如果您只想允许18岁以上的人使用该服务,则需要在服务器端进行验证(当然,他们可能会说谎)。 - Ingo Bürk
16个回答

24
如果您想在格式中使用正斜杠,则需要在正则表达式中使用反斜杠进行转义:
var pattern =/^([0-9]{2})\/([0-9]{2})\/([0-9]{4})$/;

http://jsfiddle.net/P9TER/


7
如果您愿意的话,可以考虑将{2}更改为{1,2},以允许日期格式如3/6/1990 -- 这是可选的。当然,您也可以强制用户填补零位。 - Ingo Bürk
谢谢你的建议!在使用正则表达式分隔值后,我是否可以直接对它们进行解析,还是应该在出现“/”时进行分割并将它们存储在新变量中以计算年龄? - A. Mesut Konuklar
26
这不正确,因为它可以接受像20/20/2010这样的日期。 - Anjum
2
答案不完整。缺少日期和月份的范围检查。 - Satyajit
2
它接受未来的年份,这是不被期望的。 - Monicka

14

我建议使用moment.js,它提供了一种易于使用的方法来实现这个目标。

交互演示

function validate(date){
    var eighteenYearsAgo = moment().subtract(18, "years");
    var birthday = moment(date);

    if (!birthday.isValid()) {
        return "invalid date";    
    }
    else if (eighteenYearsAgo.isAfter(birthday)) {
        return "okay, you're good";    
    }
    else {
        return "sorry, no";    
    }
}

要在您的网页中使用moment,您可以使用CDNJS:

<script src="//cdnjs.cloudflare.com/ajax/libs/moment.js/2.4.0/moment.min.js"></script>

+1. 这可能有些过度,但比重新发明轮子更可靠。 - Lim H.
这个代码会检查日期是否有效,例如 1995 年 2 月 29 日是无效日期。 - Skytiger
@Skytiger 在交互式演示中试一下吧 :-p - Brigand
我只是复制/粘贴了一下,它就像魔法般地运行了。谢谢!正是我所需要的。 - Webmaster G

8
我会利用内置的Date对象来进行验证。即使您从-切换到/,您仍然需要检查月份是否在0到12之间,日期是否在0到31之间,年份是否在1900到2013之间。
function validateDOB(){

    var dob = document.forms["ProcessInfo"]["txtDOB"].value;
    var data = dob.split("/");
    // using ISO 8601 Date String
    if (isNaN(Date.parse(data[2] + "-" + data[1] + "-" + data[0]))) {
        return false;
    }

    return true;
}

请参考https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Date/parse#Example:_Using_parse了解更多信息。

1
你知道这个小东西吗:“NaN的等值比较总是评估为false”。 - Decebal
1
建议:使用 isNan()。 - Decebal
@decebal 不,我写答案时不认为我知道那个。谢谢。 - Lim H.

5
如果你想在格式中使用正斜杠,那么你需要在正则表达式中使用反斜杠进行转义:

   
var dateformat = /^(0?[1-9]|1[012])[\/\-](0?[1-9]|[12][0-9]|3[01])[\/\-]\d{4}$/;


4
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title></title>
<script>
    function dateCheck() {
        debugger;

        var inputValues = document.getElementById('dateInput').value + ' ' + document.getElementById('monthInput').value + ' ' + document.getElementById('yearInput').value;

        var d = new Date();
        var n = d.getHours();
        var m = d.getMinutes();
        var p = d.getSeconds();

        var date = document.getElementById("dateInput").value;
        var month = document.getElementById("monthInput").value;
        var year = document.getElementById("yearInput").value;

        var dateCheck = /^(0?[1-9]|[12][0-9]|3[01])$/;
        var monthCheck = /^(0[1-9]|1[0-2])$/;
        var yearCheck = /^\d{4}$/; 

        if (month.match(monthCheck) && date.match(dateCheck) && year.match(yearCheck)) {

            var ListofDays = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];

            if (month == 1 || month > 2) {
                if (date > ListofDays[month - 1]) {
                    alert('Invalid date format!');
                    return false;
                }
            }

            if (month == 2) {
                var leapYear = false;
                if ((!(year % 4) && year % 100) || !(year % 400)) {
                    leapYear = true;
                }

                if ((leapYear == false) && (date >= 29)) {
                    alert('Invalid date format!');
                    return false;
                }

                if ((leapYear == true) && (date > 29)) {
                    alert('Invalid date format!');
                    return false;
                }

            }
            var flag = 1
        }

        else {
            alert("invalid date");


        }
        if (flag == 1) {
            alert("the date is:" + inputValues + " " + "The time is:" + n + ":" + m + ":" + p);
        }

        clear();
    }

    function clear() {
        document.myForm.dateInput.value = "";
        document.myForm.monthInput.value = "";
        document.myForm.yearInput.value = "";
    }


</script>

</head>


<body>  
    <div>  
        <form name="myForm" action="#">   
            <table>
                <tr>
                    <td>Enter Date</td>
                    <td><input type='text' name='dateInput' id="dateInput" placeholder="Date"  maxlength="2" onclick="dateCheck(document.myForm.dateInput)" onkeypress="return event.charCode === 0 || /\d/.test(String.fromCharCode(event.charCode));"/></td>
                    <td><span id="span1"></span></td>
                </tr>
                <tr>
                    <td>Enter Month</td>
                    <td><input type='text' name='monthInput' id="monthInput" placeholder="Month"  maxlength="2" onclick="dateCheck(document.myForm.dateInput)" onkeypress="return event.charCode === 0 || /\d/.test(String.fromCharCode(event.charCode));"/></td>
                    <td><span id="span2"></span></td>
                </tr>
                <tr>
                    <td>Enter Year</td>
                    <td><input type='text' name='yearInput' id="yearInput" placeholder="Year" minlength="4" maxlength="4" onclick="dateCheck()" onkeypress="return event.charCode === 0 || /\d/.test(String.fromCharCode(event.charCode));"/></td>
                    <td><span id="span3"></span></td>
                </tr>

                <tr>
                    <td></td>
                    <td><input type="submit" name="submit" value="Submit" onclick="dateCheck()"/></td>
                </tr>
            </table>
        </form>  
    </div>   
</body>  
</html>
<td>

2

使用模式和验证检查:

var input = '33/15/2000';

var pattern = /^((0[1-9]|[12][0-9]|3[01])(\/)(0[13578]|1[02]))|((0[1-9]|[12][0-9])(\/)(02))|((0[1-9]|[12][0-9]|3[0])(\/)(0[469]|11))(\/)\d{4}$/;

alert(pattern.test(input));

1
这是两个问题 - 斜杠是否放置正确以及日期是否有效。 我建议您捕获输入更改并自己添加斜杠。(用户可能会感到烦恼)
有趣的问题是他们是否输入了有效的日期,我建议利用js的灵活性:

function isValidDate(str) {
  var newdate = new Date();
  var yyyy = 2000 + Number(str.substr(4, 2));
  var mm = Number(str.substr(2, 2)) - 1;
  var dd = Number(str.substr(0, 2));
  newdate.setFullYear(yyyy);
  newdate.setMonth(mm);
  newdate.setDate(dd);
  return dd == newdate.getDate() && mm == newdate.getMonth() && yyyy == newdate.getFullYear();
}
console.log(isValidDate('jk'));//false
console.log(isValidDate('290215'));//false
console.log(isValidDate('290216'));//true
console.log(isValidDate('292216'));//false


可以将 var newdate = new Date(yyyy, mm, dd); 定义在一行中,而不是分成四行。 - Y.B.

1
您已经使用正则表达式来匹配此格式: DD - MM- YYYY
如果需要匹配格式为 DD/MM/YYYY,请使用
var pattern =/^([0-9]{2})\/([0-9]{2})\/([0-9]{4})$/;

1
你的回答为什么和Drahcir的回答完全一样,而且是在他之前2分钟就回答了呢? - Win
1
我在点击提交按钮时可能慢了一秒钟。 :) - abhiklpm

0
var date=/^[0-9]{1,2}\-[0-9]{1,2}\-[0-9]{1,4}$/;

if(!date.test(form.date.value))

alert("Enter correct date");

else
alert(" working");

不开玩笑,请为代码提供一些上下文和解释。如何回答 - AgataB

0

我使用了在w3resources找到的代码。

该代码可以处理以下情况:

  • 月份小于12,

  • 日期小于32

  • 甚至适用于闰年。

    在我的项目中使用时,我对闰年的代码进行了修改:

    if ((lyear==false) && (dd>=29))
    {
    alert('日期格式无效!');
    return false;
    }

    if ((lyear==false) && (dd>=29))
    {
    alert('不是闰年,二月不能超过28天');
    return false;
    }

而不是抛出一般性的“日期格式无效”错误,这对用户来说意义不大。

我对剩余代码进行了修改,以提供有效的错误提示,例如月份不能超过12,日期不能超过31等。

使用正则表达式的问题在于很难确定出错的具体原因。它只会返回True或False,而不会告诉我们失败的原因。为了解决这个问题,我们不得不编写多个正则表达式。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接