最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Using regexp to validate a date using DD-Mon-YYYY format - Stack Overflow

programmeradmin1浏览0评论

Hello I am trying to validate a date in the format: 03-Mar-2011 or 12-Dec-2007. I currently have a regexp that fails on the 3 character Month. I probably just need to tweak that to get it to work properly.

    //function isDate(txtDate) {
    function isDate(sender, args) {
        var currVal = document.getElementById('<%=txtChange_Date.ClientID%>').value;

            if (currVal == '')
                return false;

            //Declare Regex  
            var rxDatePattern = /^(\d{1,2})(\/|-)[a-zA-Z]{3}(\/|-)(\d{4})$/;

            var dtArray = currVal.match(rxDatePattern); // is format OK?

            if (dtArray == null)
                return false;

            //formerly //Checks for dd/mm/yyyy format.
            //Checks for dd-MMM-yyyy format.
            var dtDay = dtArray[1];
            var dtMonth = dtArray[3];
            var dtYear = dtArray[4];

            switch(dtMonth)
            {
                case 'Jan':
                    dtMonth = '01';
                    break;
                case 'Feb':
                    dtMonth = '02';
                    break;
                case 'Mar':
                    dtMonth = '03';
                    break;
                case 'Apr':
                    dtMonth = '04';
                    break;
                case 'May':
                    dtMonth = '05';
                    break;
                case 'Jun':
                    dtMonth = '06';
                    break;
                case 'Jul':
                    dtMonth = '07';
                    break;
                case 'Aug':
                    dtMonth = '08';
                    break;
                case 'Sep':
                    dtMonth = '09';
                    break;
                case 'Oct':
                    dtMonth = '10';
                    break;
                case 'Nov':
                    dtMonth = '11';
                    break;
                case 'Dec':
                    dtMonth = '12';
                    break;
            }


if (dtMonth < 1 || dtMonth > 12)
                return false;
else if (dtDay < 1 || dtDay > 31)
                return false;
else if ((dtMonth == 4 || dtMonth == 6 || dtMonth == 9 || dtMonth == 11) && dtDay == 31)
                return false;
else if (dtMonth == 2) {
            var isleap = (dtYear % 4 == 0 && (dtYear % 100 != 0 || dtYear % 400 == 0));
                if (dtDay > 29 || (dtDay == 29 && !isleap))
                    return false;
            }

            return true;
        }

Hello I am trying to validate a date in the format: 03-Mar-2011 or 12-Dec-2007. I currently have a regexp that fails on the 3 character Month. I probably just need to tweak that to get it to work properly.

    //function isDate(txtDate) {
    function isDate(sender, args) {
        var currVal = document.getElementById('<%=txtChange_Date.ClientID%>').value;

            if (currVal == '')
                return false;

            //Declare Regex  
            var rxDatePattern = /^(\d{1,2})(\/|-)[a-zA-Z]{3}(\/|-)(\d{4})$/;

            var dtArray = currVal.match(rxDatePattern); // is format OK?

            if (dtArray == null)
                return false;

            //formerly //Checks for dd/mm/yyyy format.
            //Checks for dd-MMM-yyyy format.
            var dtDay = dtArray[1];
            var dtMonth = dtArray[3];
            var dtYear = dtArray[4];

            switch(dtMonth)
            {
                case 'Jan':
                    dtMonth = '01';
                    break;
                case 'Feb':
                    dtMonth = '02';
                    break;
                case 'Mar':
                    dtMonth = '03';
                    break;
                case 'Apr':
                    dtMonth = '04';
                    break;
                case 'May':
                    dtMonth = '05';
                    break;
                case 'Jun':
                    dtMonth = '06';
                    break;
                case 'Jul':
                    dtMonth = '07';
                    break;
                case 'Aug':
                    dtMonth = '08';
                    break;
                case 'Sep':
                    dtMonth = '09';
                    break;
                case 'Oct':
                    dtMonth = '10';
                    break;
                case 'Nov':
                    dtMonth = '11';
                    break;
                case 'Dec':
                    dtMonth = '12';
                    break;
            }


if (dtMonth < 1 || dtMonth > 12)
                return false;
else if (dtDay < 1 || dtDay > 31)
                return false;
else if ((dtMonth == 4 || dtMonth == 6 || dtMonth == 9 || dtMonth == 11) && dtDay == 31)
                return false;
else if (dtMonth == 2) {
            var isleap = (dtYear % 4 == 0 && (dtYear % 100 != 0 || dtYear % 400 == 0));
                if (dtDay > 29 || (dtDay == 29 && !isleap))
                    return false;
            }

            return true;
        }
Share Improve this question edited Sep 6, 2013 at 14:01 James Montagne 78.8k14 gold badges114 silver badges132 bronze badges asked Sep 6, 2013 at 13:58 Jason TaylorJason Taylor 851 gold badge1 silver badge6 bronze badges 3
  • 1 FYI regular expressions have nothing to do with jQuery. I've edited the title for you. – Rory McCrossan Commented Sep 6, 2013 at 14:01
  • There are tested date validation scripts / libraries for JS which may be worth looking at. – Matthew Commented Sep 6, 2013 at 14:06
  • 1 Easy answer is to use moment.js's isValid function – Daniel Gimenez Commented Sep 6, 2013 at 14:10
Add a ment  | 

5 Answers 5

Reset to default 3

There were a few problems with your code, but your regular expression was fine except that month wasn't being grouped.

Other Changes

  • The switch that converts the month needed to have dtMonth converted to lower case and the case statements needed to match the case.
  • I explicitly converted the date parts to integers with parseInt. I don't know if it was an issue with dtDay or dtYear, but it was causing an issue with dtMonth.
  • With the parseInt change I added a not a number check and dtMonth.
  • I also moved the validator out of the event handler. Just a good practice to follow if the validation isn't trivial.

Code

function isDate(currVal) {
    if (currVal == '') return false;

    //Declare Regex  
    var rxDatePattern = /^(\d{1,2})(\/|-)([a-zA-Z]{3})(\/|-)(\d{4})$/;

    var dtArray = currVal.match(rxDatePattern); // is format OK?

    if (dtArray == null) return false;

    var dtDay = parseInt(dtArray[1]);
    var dtMonth = dtArray[3];
    var dtYear = parseInt(dtArray[4]);

    // need to change to lowerCase because switch is
    // case sensitive
    switch (dtMonth.toLowerCase()) {
        case 'jan':
            dtMonth = '01';
            break;
        case 'feb':
            dtMonth = '02';
            break;
        case 'mar':
            dtMonth = '03';
            break;
        case 'apr':
            dtMonth = '04';
            break;
        case 'may':
            dtMonth = '05';
            break;
        case 'jun':
            dtMonth = '06';
            break;
        case 'jul':
            dtMonth = '07';
            break;
        case 'aug':
            dtMonth = '08';
            break;
        case 'sep':
            dtMonth = '09';
            break;
        case 'oct':
            dtMonth = '10';
            break;
        case 'nov':
            dtMonth = '11';
            break;
        case 'dec':
            dtMonth = '12';
            break;
    }

    // convert date to number
    dtMonth = parseInt(dtMonth);

    if (isNaN(dtMonth)) return false;
    else if (dtMonth < 1 || dtMonth > 12) return false;
    else if (dtDay < 1 || dtDay > 31) return false;
    else if ((dtMonth == 4 || dtMonth == 6 || dtMonth == 9 || dtMonth == 11) && dtDay == 31) return false;
    else if (dtMonth == 2) {
        var isleap = (dtYear % 4 == 0 && (dtYear % 100 != 0 || dtYear % 400 == 0));
        if (dtDay > 29 || (dtDay == 29 && !isleap)) return false;
    }

    return true;
}

jsFiddle

Alternate Solution

You might not like a really plicated regex, but you can really reduce your code by handling the switching in the regex itself. The following gets the matched month by looping through the matched group into an undefined one is not encountered and then offsetting the value.

function isDate(currVal) {

    if (currVal == '') return false;

    //Declare Regex  
    var rxDatePattern = /^(\d{1,2})(\/|-)(?:(\d{1,2})|(jan)|(feb)|(mar)|(apr)|(may)|(jun)|(jul)|(aug)|(sep)|(oct)|(nov)|(dec))(\/|-)(\d{4})$/i;

    var dtArray = currVal.match(rxDatePattern);

    if (dtArray == null) return false;

    var dtDay = parseInt(dtArray[1]);
    var dtMonth = parseInt(dtArray[3]);
    var dtYear = parseInt(dtArray[17]);

    if (isNaN(dtMonth)) {
        for (var i = 4; i <= 15; i++) {
            if ((dtArray[i])) {
                dtMonth = i - 3;
                break;
            }
        }
    }

    if (dtMonth < 1 || dtMonth > 12) return false;
    else if (dtDay < 1 || dtDay > 31) return false;
    else if ((dtMonth == 4 || dtMonth == 6 || dtMonth == 9 || dtMonth == 11) && dtDay == 31) return false;
    else if (dtMonth == 2) {
        var isleap = (dtYear % 4 == 0 && (dtYear % 100 != 0 || dtYear % 400 == 0));
        if (dtDay > 29 || (dtDay == 29 && !isleap)) return false;
    }

    return true;
}

jsFiddle

your regex is ok, you haven't enclosed the month subpattern with parentheses so you haven't defined a capture group. consequently, your switch statement fails:

try

var rxDatePattern = /^(\d{1,2})(\/|-)([a-zA-Z]{3})(\/|-)(\d{4})$/;

and

var dtYear = dtArray[5];  // now 5 instead of 4

You need parentheses around the month to capture it:

/^(\d{1,2})(\/|-)([a-zA-Z]{3})(\/|-)(\d{4})$/

Which will mean you then need to adjust the index of your year:

var dtYear = dtArray[5];  // now 5 instead of 4

It looks like there's just brackets missing around the month section to make it a separate group.

        /^(\d{1,2})(\/|-)([a-zA-Z]{3})(\/|-)(\d{4})$/

        var dtDay = dtArray[1];
        var dtMonth = dtArray[3];
        var dtYear = dtArray[5];

Here is the code, no regexp required and use of javascript build in date parsing.

var isDate = (function() {
    var MONTHS = [
        "Jan", 
        "Feb", 
        "Mar", 
        "Apr", 
        "May", 
        "Jun", 
        "Jul",
        "Aug",
        "Sep",
        "Oct",
        "Nov",
        "Dec"
    ];

    return function (date) {
        var v = new Date(date);
        var day = v.getDate();
        if(day < 10) {
            day = "0" + day;
        }
        var month = MONTHS[v.getMonth()];
        var year = v.getFullYear();
        var total = day + "-" + month + "-" + year;
        return date.toUpperCase() == total.toUpperCase();
    }
}());

THE FIDDLE

发布评论

评论列表(0)

  1. 暂无评论
ok 不同模板 switch ($forum['model']) { /*case '0': include _include(APP_PATH . 'view/htm/read.htm'); break;*/ default: include _include(theme_load('read', $fid)); break; } } break; case '10': // 主题外链 / thread external link http_location(htmlspecialchars_decode(trim($thread['description']))); break; case '11': // 单页 / single page $attachlist = array(); $imagelist = array(); $thread['filelist'] = array(); $threadlist = NULL; $thread['files'] > 0 and list($attachlist, $imagelist, $thread['filelist']) = well_attach_find_by_tid($tid); $data = data_read_cache($tid); empty($data) and message(-1, lang('data_malformation')); $tidlist = $forum['threads'] ? page_find_by_fid($fid, $page, $pagesize) : NULL; if ($tidlist) { $tidarr = arrlist_values($tidlist, 'tid'); $threadlist = well_thread_find($tidarr, $pagesize); // 按之前tidlist排序 $threadlist = array2_sort_key($threadlist, $tidlist, 'tid'); } $allowpost = forum_access_user($fid, $gid, 'allowpost'); $allowupdate = forum_access_mod($fid, $gid, 'allowupdate'); $allowdelete = forum_access_mod($fid, $gid, 'allowdelete'); $access = array('allowpost' => $allowpost, 'allowupdate' => $allowupdate, 'allowdelete' => $allowdelete); $header['title'] = $thread['subject']; $header['mobile_link'] = $thread['url']; $header['keywords'] = $thread['keyword'] ? $thread['keyword'] : $thread['subject']; $header['description'] = $thread['description'] ? $thread['description'] : $thread['brief']; $_SESSION['fid'] = $fid; if ($ajax) { empty($conf['api_on']) and message(0, lang('closed')); $apilist['header'] = $header; $apilist['extra'] = $extra; $apilist['access'] = $access; $apilist['thread'] = well_thread_safe_info($thread); $apilist['thread_data'] = $data; $apilist['forum'] = $forum; $apilist['imagelist'] = $imagelist; $apilist['filelist'] = $thread['filelist']; $apilist['threadlist'] = $threadlist; message(0, $apilist); } else { include _include(theme_load('single_page', $fid)); } break; default: message(-1, lang('data_malformation')); break; } ?>