输入日期的检测

    (一) 最近用VS2005开发ASP.Net页面,用到了验证控件,验证日期时,学了一点正则表达式的写法,发现书上的一种写法无法验证,于是自己写了一下,请大家多多指教。

书上的写法: "/(?:0[1-9]|[12]][0-9]|3[01])\ /(?:0[1-9]|1[0-2])\ /(?:19|20\d{2})/"

验证的日期格式为: "dd/mm/yyyy"

我的写法: "((19|20)\d{2})/((0[1-9])|(1[0-2]))/((0[1-9])|([12][0-9])|(3[01]))"

验证的日期格式为: "yyyy/mm/dd"

如果将输入的最大长度定为 10,可以少很多麻烦。

 

     (二) 扩展

正则表达式写为: "((19|20)\d{2})(/|-| |.)((0[1-9])|(1[0-2]))(/|-| |.)((0[1-9])|([12][0-9])|(3[01]))\s*"

这样,在年月与月日之间的分隔符就可以是'/', '-', '.', ' ', '',及支持的格式扩大为:

(1)"yyyy/mm/dd"     (2)"yyyy-mm-dd"     (3)"yyyy.mm.dd"     (4)"yyyy mm dd"     

而且在正则表达式后面增加了"\s*",这样,在输入完日期后,即使不小心多输了空白字符,也不会算错。

但这样扩展之后,会出现一种错误的格式,如"yyyy/mm-dd",这种格式在验证时,不会出错,但转换为时间的时候就有问题了,因此要增加一些限制,我采取的做法是增加javascript检测,如下:

function checkSeparator()
{
    var sInput;        
    sInput = document.getElementById("TextDate").value;    //获取输入字符串
    
    if((sInput.indexOf("/") > 0) && (sInput.indexOf("/") == sInput.lastIndexOf("/")))
    {
        alert("分隔符不一致!");
        return false;
    }
    if((sInput.indexOf("-") > 0) && (sInput.indexOf("-") == sInput.lastIndexOf("-")))
    {
        alert("分隔符不一致!");
        return false;
    }
    if((sInput.indexOf(".") > 0) && (sInput.indexOf(".") == sInput.lastIndexOf(".")))
    {
        alert("分隔符不一致!");
        return false;
    }
    if((sInput.indexOf(" ") > 0) && (sInput.indexOf(" ") == sInput.lastIndexOf(" ")))
    {
        alert("分隔符不一致!");
        return false;
    }
   
    return true;  

}

这样,就可以把分隔符不一致的情况排除。

 

     (三)也许,细心一点的读者已经发现了上面这两种方法都存在缺陷。

(1)日期验证不够精确,如1,3,5,7,8,10,12月都是31天;4,6,9,11月都是30天,2月28天或29天;

(2)在扩展中允许最后输入空格,在判断空格为分隔符时,meiyou排除最后的空格带来的影响。(调查结果javascript的String对象的方法中没有找到trim()方法,恐怕要自己写trim()函数来去除结尾的空白,由于空白字符是看不见的,如果结尾有空白算错误的话,用户也许会产生迷惑,因为表面看来输入日期是正确的)

 

     自己用javascript写个trim()函数并不难(除非你不会javascript),在这里只给出缺陷(1)的解决办法。由于在验证表达式中判断闰年很复杂,这里给出一种javascript判断日期的方法。

function checkStrDate(strSearchDate)
{
    if(strSearchDate.length <= 0)
    {
        return true;
    }
   
    var strMsg="日期格式不正确";
   
    var arrSeparators = "/-. "
    var currSep = 0;
    var iPosFirst = -1;
    var iPosLast = -1;
    var bNumValid = false;
    for (var i=0; i < 4; i++)
    {
        currSep = arrSeparators.charAt(i);
        iPosFirst = strSearchDate.indexOf(currSep);
        iPosLast = strSearchDate.lastIndexOf(currSep);
        if((iPosFirst > 0) && (iPosLast > 0) && (iPosFirst != iPosLast))
        {
            var strArrTmp = strSearchDate.split(currSep,3);
            var year = Number(strArrTmp[0],10);
            if(year != year) continue;
            var month = Number(strArrTmp[1],10);
            if(month != month) continue;
            var day = Number(strArrTmp[2],10);
            if(day != day) continue;
            bNumValid = true;
            break;
        }
    }  
   
    if(!bNumValid)
    {
        var iPosYear = strSearchDate.indexOf("年",0);
        if( iPosYear < 0)
        {
            alert(strMsg);           
            return false;
        }
       
        var iPosMonth = strSearchDate.indexOf("月",iPosYear);
        if( iPosMonth < 0)
        {  
            alert(strMsg);        
            return false;
        }
       
        var iPosDay = strSearchDate.indexOf("日",iPosMonth);
        if( iPosDay < 0)
        {
            iPosDay = strSearchDate.length;                       
        }
       
        var sYear = strSearchDate.substring(0,iPosYear);
        var sMonth = strSearchDate.substring(iPosYear+1,iPosMonth);
        var sDay = strSearchDate.substring(iPosMonth+1,iPosDay);
       
        var year = Number(sYear,10);
        if(year != year)
        {
            alert(strMsg);
            return false;
        }
        var month = Number(sMonth, 10);
        if(month != month)
        {
            alert(strMsg);
            return false;
        }
        var day = Number(sDay,10);
        if(day != day)
        {
            alert(strMsg);
            return false;
        }
        bNumValid = true;
    }
   
    if(!bNumValid)
    {
        alert(strMsg);
        return false;
    }
    if((year > 2099) || (year < 1900))
    {
        alert(strMsg);
        return false;
    }
    if((month > 12) || (month < 1))
    {
        alert(strMsg);
        return false;
    }
    if((day > 31) || (day < 1))
    {
        alert(strMsg);
        return false;
    }
    if((day > 30) && ((month == 4) || (month == 6) || (month == 9) || (month == 11)))
    {
        alert(strMsg);
        return false;
    }
    var bLeapYear=((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0);
   
    if((bLeapYear) && ((month == 2) && (day > 29)))
    {
        alert(strMsg);
        return false;
    }             
    if((!bLeapYear) && ((month == 2) && (day > 28)))
    {
        alert(strMsg);
        return false;
    }
   
    return true;
}

 

应用这种方法,可以不使用验证控件。这里多了对“年月日”的支持,值得注意的是,在javascript中,一个汉字于一个英文字符所占的空间是一样的。

 

注:本文代码在VS2005运行正常

 

posted @ 2008-08-25 15:16  鴻鵠唐  阅读(156)  评论(0编辑  收藏  举报