javascriptRegex驗證日期(區別平年和閏年)

來源:互聯網
上載者:User

DateTime 實值型別表示值範圍在公元(基督紀元)0001 年 1 月 1 日午夜 12:00:00 到公元 (C.E.) 9999 年 12 月 31 日晚上 11:59:59 之間的日期和時間。

我們進入正題。
首先需要驗證年份,顯然,年份範圍為 0001 - 9999,匹配YYYY的Regex為:

[0-9]{3}[1-9]|[0-9]{2}[1-9][0-9]{1}|[0-9]{1}[1-9][0-9]{2}|[1-9][0-9]{3}
其中 [0-9] 也可以表示為 /d,但 /d 不如 [0-9] 直觀,因此下面我將一直採用 [0-9]

用Regex驗證日期的痛點有二:一是大小月份的天數不同,二是閏年的考慮。
對於第一個痛點,我們首先不考慮閏年,假設2月份都是28天,這樣,月份和日期可以分成三種情況:

下面僅考慮月和日的正則
 
1. 包括平年在內的所有年份的月份都包含1-28日
 
(0[1-9]|1[0-2])-(0[1-9]|1[0-9]|2[0-8])
 
2. 包括平年在內的所有年份除2月外都包含29和30日
 
(0[13-9]|1[0-2])-(29|30)
 
3. 包括平年在內的所有年份1、3、5、7、8、10、12月都包含31日
 
(0[13578]|1[02])-31)
 
合起來就是除閏年的2月29日外的其它所有日期
 
(?!0000)[0-9]{4}-((0[1-9]|1[0-2])-(0[1-9]|1[0-9]|2[0-8])|(0[13-9]|1[0-2])-(29|30)|(0[13578]|1[02])-31)


接著我們來解決第二個痛點:閏年的考慮。根據閏年的定義,我們可以將閏年分為兩類:

1、能被4整除但不能被100整除的年份。尋找後兩位的變化規律,可以很快得到下面的正則匹配:
([0-9]{2})(0[48]|[2468][048]|[13579][26])
2、能被400整除的年份。能被400整除的數肯定能被100整除,因此後兩位肯定是00,我們只要保證前兩位能被4整除即可,相應的Regex為:
(0[48]|[2468][048]|[3579][26])00
2.最強驗證日期的Regex,添加了閏年的驗證

這個日期Regex支援
YYYY-MM-DD
YYYY/MM/DD
YYYY_MM_DD
YYYY.MM.DD的形式

match : 2008-2-29 2008/02/29

not match : 2008-2-30   2007-2-29


1 : 四年一閏
([0-9]{2}(0[48]|[2468][048]|[13579][26])
 
2 : 百年不閏,四百年再閏
(0[48]|[2468][048]|[13579][26])00
 
3 : 合起來就是所有閏年的2月29日
([0-9]{2}(0[48]|[2468][048]|[13579][26])|(0[48]|[2468][048]|[13579][26])00)-02-29)
 
四條規則都已實現,且互相間沒有影響,合起來就是所有符合DateTime範圍的日期的正則
 
^((?!0000)[0-9]{4}-((0[1-9]|1[0-2])-(0[1-9]|1[0-9]|2[0-8])|(0[13-9]|1[0-2])-(29|30)|(0[13578]|1[02])-31)|([0-9]{2}(0[48]|[2468][048]|[13579][26])|(0[48]|[2468][048]|[13579][26])00)-02-29)$
 
考慮到這個Regex僅僅是用作驗證,所以擷取的群組沒有意義,只會佔用資源,影響匹配效率,所以可以使用非擷取的群組來進行最佳化。
 
^(?:(?!0000)[0-9]{4}-(?:(?:0[1-9]|1[0-2])-(?:0[1-9]|1[0-9]|2[0-8])|(?:0[13-9]|1[0-2])-(?:29|30)|(?:0[13578]|1[02])-31)|(?:[0-9]{2}(?:0[48]|[2468][048]|[13579][26])|(?:0[48]|[2468][048]|[13579][26])00)-02-29)$

 

總合上面我們寫個完美的日期驗證函式

 代碼如下 複製代碼

function CheckDate(strDate){
    //var strDate = document.getElementById("date_hour").value;
     var reg=/^(/d{4})(/d{2})(/d{2})$/;
     if(!reg.test(strDate)){
         alert("日期格式不正確!/n正確格式為:20040101");
         return false;
      }
      //var ss=strDate.split("/");
      //var year=ss[0];
      //var month=ss[1];
      //var date=ss[2];
      var year=strDate.substring(0,4);
      var month=strDate.substring(4,6);
      var date=strDate.substring(6,8);
      //alert(year+month+date);
      if(!checkYear(year)){return false;}
      if(!checkMonth(month)){return false;}
      if(!checkDate(year,month,date)){return false;}
      return true;
  }
 function checkYear(year){
     if(isNaN(parseInt(year))){
      alert("年份輸入有誤,請重新輸入!");
          return false;
     }
     else if(parseInt(year)<1950 || parseInt(year) >2050)
     {
         alert("年份應該在1950-2050之間!");
         return false;
     }
     else return true;
  }
 function checkMonth(month){
  if(isNaN(parseInt(month,10))){alert("月份輸入有誤,請重新輸入!"); return false;}
      else if(parseInt(month,10)<1 || parseInt(month,10) >12)
      { alert("月份應該在1-12之間!");
      return false;}
      else return true;
  }
 function checkDate(year,month,date){
  var daysOfMonth=CalDays(parseInt(year),parseInt(month));
  if(isNaN(parseInt(date))){alert("日期輸入有誤,請重新輸入!"); return false;}
      else if(parseInt(date)<1||parseInt(date)>daysOfMonth){ alert("日期應該在1-"+daysOfMonth+"之間!"); return false;}
      else return true;
  }
 function CalDays(year,month){
  var date= new Date(year,month,0);
  return date.getDate();
  }
 function isLeapYear(year){
  if((year %4==0 && year %100!=0) || (year %400==0)) return true;
  else return false;
  }

總結

能被400整除的年份。能被400整除的數肯定能被100整除,因此後兩位肯定是00,我們只要保證前兩位能被4整除即可,相應的Regex為,
關於西曆閏年是這樣規定的:地球繞太陽公轉一周叫做一迴歸年,一迴歸年長365日5時48分 46秒。因此,西曆規定有平年和閏年,平年一年有365日,比迴歸年短0.2422日,四年共短0.9688日,故每四年增加一日,這一年有366日,就 是閏年。但四年增加一日比四個迴歸年又多0.0312日,400年後將多3.12日,故在400年中少設3個閏年,也就是在400年中只設97個閏年,這 樣西曆年的平均長度與迴歸年就相近似了。由此規定:年份是整百數的必須是400的倍數才是閏年,例如1900年、2100年就不是閏年。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.