java正則表達(dá)式校驗(yàn)日期格式實(shí)例代碼
1 引言
我們時(shí)常會(huì)遇到,判斷一個(gè)String是不是合法的日期格式。當(dāng)其是一個(gè)正確的日期時(shí),我們還需要判斷其格式是否符合我們的規(guī)范,常見格式如下:
- yyyyMMdd (20220929)
- yyyy-MM-dd (2022-09-29)
- yyyy/MM/dd (2022/09/29)
- yyyy.MM.dd (2022.09.29)
對(duì)于這些不同的格式來說,其實(shí)我們只要確定了年月日,再根據(jù)不同的格式來微調(diào)我們的正則表達(dá)式即可。因此本篇講解以格式 yyyyMMdd
為例。其他格式不再詳解,其正則表達(dá)式微調(diào)即可得到,這里就不贅述了。
2 基礎(chǔ)知識(shí)
2.1 什么是正確的日期
MSDN中定義的DateTime對(duì)象的有效范圍是:0001-01-01 00:00:00到9999-12-31 23:59:59。
- 因此我們篩選的日期為
00010101
到99991231
(以格式yyyyMMdd
為例,后文將不再強(qiáng)調(diào))
其次,對(duì)于日歷中大家都知道的 大月 和 小月,這里也不再贅述。
在小月中有個(gè)特殊的 2月
,它一個(gè)月只有28 或 29天,而其具體的天數(shù)根據(jù)是否為 閏年 來決定。
2.2 什么是閏年
我們通過計(jì)算方式的不同,將閏年分為 普通閏年 和 世紀(jì)閏年。
- 普通閏年:公歷年份是4的倍數(shù),且不是100的倍數(shù)的,為閏年(如2004年、2020年等就是閏年)。
- 世紀(jì)閏年:公歷年份是整百數(shù)的,必須是400的倍數(shù)才是閏年(如1900年不是閏年,2000年是閏年)。
2.3 正則表達(dá)式基礎(chǔ)
由于正則表達(dá)式的知識(shí)比較繁多,這里不做過多的介紹。只對(duì)本文將用到的表達(dá)式進(jìn)行講解。
字符 | 描述 |
---|---|
| | 指明兩項(xiàng)之間的一個(gè)選擇,意為或 。 |
\d | 匹配一個(gè)數(shù)字字符。等價(jià)于 [0-9]。 |
{n} | n 是一個(gè)非負(fù)整數(shù)。匹配確定的 n 次。 |
[1-9] | [1-9] 表示一個(gè)區(qū)間,匹配1-9的數(shù)字 |
[ABC] | 匹配 […] 中的所有字符,例如 [358] 匹配數(shù)字 3、5、8 |
接下來我們將這些簡(jiǎn)單的字符進(jìn)行一個(gè)組合,看看你是否還能理解他們的意思呢?
正則表達(dá)式 | 描述 | 舉例文本 | 錯(cuò)誤文本 |
---|---|---|---|
\d{3} | 3個(gè)數(shù)字都是0-9的間的數(shù)字 | 237、832、129 | a37、ufo |
\d{3}[1-9] | 前3個(gè)數(shù)字都是0-9的間的數(shù)字,第四個(gè)數(shù)字是1-9直接的數(shù)字 | 2372、4041、9001 | 8720、2020 |
[7-9]|[523] | 該數(shù)字要么是7-9之間的一個(gè)數(shù),要么是2,3,5其中的一個(gè)數(shù)字 | 7、5、2 | 1、4、6 |
簡(jiǎn)單的學(xué)會(huì)使用正則表達(dá)式了,那我們就開始正式的開始書寫吧。
3 構(gòu)造正則表達(dá)式
3.1 閏年的情況
為了方便后面的表示,我們將 yyyy 變?yōu)?y1y2y3y4
3.1.1 世紀(jì)閏年的情況
- 世紀(jì)閏年:公歷年份是整百數(shù)的,必須是400的倍數(shù)才是閏年(如1900年不是閏年,2000年是閏年)。
由 世紀(jì)閏年 的定義我們可以知道,y3 和 y4 一定是0的,因此可得如下表格:
y1 | y2 | y3 | y4 |
---|---|---|---|
待定 | 待定 | 0 | 0 |
現(xiàn)在來討論 y1 和 y2,由定義可知,我們可知 y1y2這個(gè)二位數(shù)一定是4的倍數(shù)。4的倍數(shù)的二位數(shù)一共有:
- 04、08、12、16、20、
- 24、28、32、36、40、
- 44、48、52、56、60、
- 64、68、72、76、80、
- 84、88、92、96、
相信大家也看出規(guī)律了,因此可得如下表格:
y1 | y2 | y1y2 | y3 | y4 |
---|---|---|---|---|
0 | [48] | 0[48] | 0 | 0 |
[2468] | [48] | [2468][048] | 0 | 0 |
[3579] | [48] | [3579][26] | 0 | 0 |
可以看到,此時(shí)有3種情況,這里我們用 | 將其聯(lián)系起來成為一條正則表達(dá)式,如下:
((0[48]|[2468][048]|[3579][26])00)
3.1.2 普通閏年的情況
- 普通閏年:公歷年份是4的倍數(shù),且不是100的倍數(shù)的,為閏年(如2004年、2020年等就是閏年)。
因此在此我們只需要判斷,y1y2y3y4 是否為4的倍數(shù)即可,但這里也想上面把所有情況列出來找規(guī)律嗎?這里可是4位數(shù),情況將遠(yuǎn)遠(yuǎn)大于2位數(shù)的情況。這里我們來找找有沒有什么可以減少位數(shù)的方法呢?
所以 y1y200 不管 y1y2 為何值都為4的倍數(shù),可得下表:
y1 | y2 | y1y2 | y3 | y4 |
---|---|---|---|---|
\d | \d | \d{2} | 待定 | 待定 |
而我們可以知道,一個(gè)為4的倍數(shù)的數(shù),只有加上一個(gè)為4的倍數(shù),和才能為4的倍數(shù)。故我們現(xiàn)在只需要求 y3y4 為4的情況即可,我們按照之前列舉的方法可得如下表:
y1 | y2 | y1y2 | y3 | y4 |
---|---|---|---|---|
\d | \d | \d{2} | 0 | [48] |
\d | \d | \d{2} | [2468] | [48] |
\d | \d | \d{2} | [13579] | [26] |
這里我們用 | 將其聯(lián)系起來成為一條正則表達(dá)式,如下:
(\d{2})(0[48]|[2468][048]|[13579][26])
3.1.3 閏年的特殊日期
我們可以知道閏年的特殊之處在于2月29日
這一天是否存在,其他日子不存在閏年與平年的區(qū)別。因此我們只需要在閏年的情況下,判斷2月29日這一天的日子即可,故可得以下正則表達(dá)式:
世紀(jì)閏年:(\d{2})(0[48]|[2468][048]|[13579][26])0229 普通閏年:((0[48]|[2468][048]|[3579][26])00)0229
用 | 將其聯(lián)系起來成為一條正則表達(dá)式,如下:
(((\d{2})(0[48]|[2468][048]|[13579][26])|((0[48]|[2468][048]|[3579][26])00))0229)
3.2 其他情況
現(xiàn)在解決了 2月29日
這個(gè)棘手的問題,對(duì)于其他日子,我們將不在區(qū)分閏年。看到這你是不是以為就可以直接 \d{4}
來表示y1y2y3y4 了?
看來你忽略了一個(gè)條件,在 2.2.1
中我們明確了時(shí)間的范圍為為 00010101
到 99991231
,但當(dāng) y1y2y3y4 為 \d{4}
存在 0000
這個(gè)情況,顯然這個(gè)數(shù)據(jù)并不在我們合法的范圍中。
因此我們可以得到如下的表:
y1 | y2 | y3 | y4 |
---|---|---|---|
\d | \d | \d | [1-9] |
\d | \d | [1-9] | \d |
\d | [1-9] | \d | \d |
[1-9] | \d | \d | \d |
用 | 將其聯(lián)系起來成為一條正則表達(dá)式,如下:
(\d{3}[1-9]|\d{2}[1-9]\d|\d[1-9]\d{2}|[1-9]\d{3})
然后就是構(gòu)造 月
和 日
的正則表達(dá)式了
3.2.1 大月
首先是大月為:01,03,05,07,08,10,12。
正則表達(dá)式如下:
(0[13578]|1[02])
大月每月的日子從1日-31日均有。
正則表達(dá)式如下:
(0[1-9]|[12]\d|3[01])
故大月的正則表達(dá)式為:
((0[13578]|1[02])(0[1-9]|[12]\d|3[01]))
3.2.2 小月
首先是小月為:02,04,06,09,11。(但2月的日子和其他小月不同,這里將排除掉2月)
正則表達(dá)式如下:
(0[469]|11)
小月(不含2月)每月的日子從1日-30日均有。
正則表達(dá)式如下:
(0[1-9]|[12]\d|30)
故小月(除2月)的正則表達(dá)式為:
(0[469]|11)(0[1-9]|[12]\d|30))
3.2.3 2月
因?yàn)榍懊嫖覀円呀?jīng)特殊表示了2月29日,所以這里我們只需要考慮2月的1日到28日,正則表達(dá)式如下:
(02(0[1-9]|[1]\d|2[0-8])
3.3 完整表達(dá)式
現(xiàn)在我們將全年的年月日均表達(dá)出來了,我們將其用 | 聯(lián)系起來可得如下正則表達(dá)式(不包含2月29日):
((\d{3}[1-9]|\d{2}[1-9]\d|\d[1-9]\d{2}|[1-9]\d{3})(((0[13578]|1[02])(0[1-9]|[12]\d|3[01]))|((0[469]|11)(0[1-9]|[12]\d|30))|(02(0[1-9]|[1]\d|2[0-8]))))
4 總結(jié)
經(jīng)過前面的努力,我們得到了如下的兩個(gè)表達(dá)式:
閏年2月29日情況: (((\d{2})(0[48]|[2468][048]|[13579][26])|((0[48]|[2468][048]|[3579][26])00))0229) 不含2月29日情況: ((\d{3}[1-9]|\d{2}[1-9]\d|\d[1-9]\d{2}|[1-9]\d{3})(((0[13578]|1[02])(0[1-9]|[12]\d|3[01]))|((0[469]|11)(0[1-9]|[12]\d|30))|(02(0[1-9]|[1]\d|2[0-8]))))
最終我們將這兩個(gè)情況,用 | 聯(lián)系起來,我們就得到了校驗(yàn)日期的正則表達(dá)式了!
((\d{3}[1-9]|\d{2}[1-9]\d|\d[1-9]\d{2}|[1-9]\d{3})(((0[13578]|1[02])(0[1-9]|[12]\d|3[01]))|((0[469]|11)(0[1-9]|[12]\d|30))|(02(0[1-9]|[1]\d|2[0-8]))))|(((\d{2})(0[48]|[2468][048]|[13579][26])|((0[48]|[2468][048]|[3579][26])00))0229)
到此這篇關(guān)于java正則表達(dá)式校驗(yàn)日期格式的文章就介紹到這了,更多相關(guān)java正則校驗(yàn)日期格式內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java線性結(jié)構(gòu)中的雙向鏈表實(shí)現(xiàn)原理
這篇文章將給大家詳細(xì)講解雙向鏈表的內(nèi)容,尤其是會(huì)通過代碼來進(jìn)行鏈表的操作,文中的代碼示例介紹的非常詳細(xì),具有一定的參考價(jià)值,需要的朋友可以參考下2023-07-07SpringBoot嵌入式Servlet容器與定制化組件超詳細(xì)講解
這篇文章主要介紹了SpringBoot嵌入式Servlet容器與定制化組件的使用介紹,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)吧2022-10-10Java?Collection接口中的常用方法總結(jié)
這篇文章將大概用代碼案例簡(jiǎn)單總結(jié)一下?Collection?接口中的一些方法,我們會(huì)以他的實(shí)現(xiàn)類?Arraylist?為例創(chuàng)建對(duì)象??煲黄饋砜纯窗?/div> 2022-12-12Java基于字符流形式讀寫數(shù)據(jù)的兩種實(shí)現(xiàn)方法示例
這篇文章主要介紹了Java基于字符流形式讀寫數(shù)據(jù)的兩種實(shí)現(xiàn)方法示,結(jié)合實(shí)例形式分析了java逐個(gè)字符讀寫及使用緩沖區(qū)進(jìn)行讀寫操作的具體實(shí)現(xiàn)技巧,需要的朋友可以參考下2018-01-01spring定時(shí)器@Scheduled異步調(diào)用方式
在Spring Boot中,@Schedule默認(rèn)使用單線程執(zhí)行定時(shí)任務(wù),多個(gè)定時(shí)器會(huì)按順序執(zhí)行,為實(shí)現(xiàn)異步執(zhí)行,可以通過自定義線程池或?qū)崿F(xiàn)SchedulingConfigurer接口,使用自定義線程池可以保證多個(gè)定時(shí)器并發(fā)執(zhí)行2024-11-11Java中通過Class類獲取Class對(duì)象的方法詳解
這篇文章主要給大家介紹了關(guān)于Java中通過Class類獲取Class對(duì)象的方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用java具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面跟著小編來一起學(xué)習(xí)學(xué)習(xí)吧。2017-08-08最新評(píng)論