【正则表达式 】java 正则表达式 校验日期格式

【正则表达式 】java 正则表达式 校验日期格式

版权声明:本文为CSDN博主「RanLZ」的原创文章,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/RangeLZ/article/details/127109751

1 引言

我们时常会遇到,判断一个String是不是合法的日期格式。当其是一个正确的日期时,我们还需要判断其格式是否符合我们的规范,常见格式如下:

  • yyyyMMdd (20220929)
  • yyyy-MM-dd (2022-09-29)
  • yyyy/MM/dd (2022/09/29)
  • yyyy.MM.dd (2022.09.29)

对于这些不同的格式来说,其实我们只要确定了年月日,再根据不同的格式来微调我们的正则表达式即可。因此本篇讲解以格式 yyyyMMdd 为例。其他格式不再详解,其正则表达式微调即可得到,这里就不赘述了。

2 基础知识

2.1 什么是正确的日期

MSDN中定义的DateTime对象的有效范围是:0001-01-01 00:00:00到9999-12-31 23:59:59。

  • 因此我们筛选的日期为 0001010199991231 (以格式 yyyyMMdd 为例,后文将不再强调)

其次,对于日历中大家都知道的 大月小月,这里也不再赘述。

在小月中有个特殊的 2月 ,它一个月只有28 或 29天,而其具体的天数根据是否为 闰年 来决定。

2.2 什么是闰年

我们通过计算方式的不同,将闰年分为 普通闰年世纪闰年

  • 普通闰年:公历年份是4的倍数,且不是100的倍数的,为闰年(如2004年、2020年等就是闰年)。
  • 世纪闰年:公历年份是整百数的,必须是400的倍数才是闰年(如1900年不是闰年,2000年是闰年)。

2.3 正则表达式基础

由于正则表达式的知识比较繁多,这里不做过多的介绍。只对本文将用到的表达式进行讲解。

字符描述
|指明两项之间的一个选择,意为
\d匹配一个数字字符。等价于 [0-9]。
{n}n 是一个非负整数。匹配确定的 n 次。
[1-9][1-9] 表示一个区间,匹配1-9的数字
[ABC]匹配 […] 中的所有字符,例如 [358] 匹配数字 3、5、8

接下来我们将这些简单的字符进行一个组合,看看你是否还能理解他们的意思呢?

正则表达式描述举例文本错误文本
\d{3}3个数字都是0-9的间的数字237、832、129a37、ufo
\d{3}[1-9]前3个数字都是0-9的间的数字,第四个数字是1-9直接的数字2372、4041、90018720、2020
[7-9]|[523]该数字要么是7-9之间的一个数,要么是2,3,5其中的一个数字7、5、21、4、6

简单的学会使用正则表达式了,那我们就开始正式的开始书写吧。

3 构造正则表达式

3.1 闰年的情况

为了方便后面的表示,我们将 yyyy 变为 y1y2y3y4

3.1.1 世纪闰年的情况
  • 世纪闰年:公历年份是整百数的,必须是400的倍数才是闰年(如1900年不是闰年,2000年是闰年)。

世纪闰年 的定义我们可以知道,y3 和 y4 一定是0的,因此可得如下表格:

y1y2y3y4
待定待定00

现在来讨论 y1 和 y2,由定义可知,我们可知 y1y2这个二位数一定是4的倍数。4的倍数的二位数一共有:

  • 04、08、12、16、20、
  • 24、28、32、36、40、
  • 44、48、52、56、60、
  • 64、68、72、76、80、
  • 84、88、92、96、

相信大家也看出规律了,因此可得如下表格:

y1y2y1y2y3y4
0[48]0[48]00
[2468][48][2468][048]00
[3579][48][3579][26]00

可以看到,此时有3种情况,这里我们用 | 将其联系起来成为一条正则表达式,如下:

((0[48]|[2468][048]|[3579][26])00)
3.1.2 普通闰年的情况
  • 普通闰年:公历年份是4的倍数,且不是100的倍数的,为闰年(如2004年、2020年等就是闰年)。

因此在此我们只需要判断,y1y2y3y4 是否为4的倍数即可,但这里也想上面把所有情况列出来找规律吗?这里可是4位数,情况将远远大于2位数的情况。这里我们来找找有没有什么可以减少位数的方法呢?

∵ \because y1y2y3y4 = = = y1y200 + y3y4
∵ \because y1y200 = 100 ∗ m ( m ∈ N ) = 100 * m(m \in N) =100mmN
∴ \therefore y1y2y3y4 = 100 ∗ m = 100 * m =100m + y3y4 ( m ∈ N ) (m \in N) mN
∵ 100 = 4 ∗ 25 \because 100 = 4 * 25 100=425
∴ 100 为 4 的 倍 数 \therefore 100为4的倍数 1004
∴ \therefore y1y200 = 4 ∗ 25 ∗ m ( m ∈ N ) , 为 4 的 倍 数 = 4 * 25 * m(m \in N),为4的倍数 =425mmN4

所以 y1y200 不管 y1y2 为何值都为4的倍数,可得下表:

y1y2y1y2y3y4
\d\d\d{2}待定待定

而我们可以知道,一个为4的倍数的数,只有加上一个为4的倍数,和才能为4的倍数。故我们现在只需要求 y3y4 为4的情况即可,我们按照之前列举的方法可得如下表:

y1y2y1y2y3y4
\d\d\d{2}0[48]
\d\d\d{2}[2468][48]
\d\d\d{2}[13579][26]

这里我们用 | 将其联系起来成为一条正则表达式,如下:

(\d{2})(0[48]|[2468][048]|[13579][26])
3.1.3 闰年的特殊日期

我们可以知道闰年的特殊之处在于2月29日 这一天是否存在,其他日子不存在闰年与平年的区别。因此我们只需要在闰年的情况下,判断2月29日这一天的日子即可,故可得以下正则表达式:

世纪闰年:(\d{2})(0[48]|[2468][048]|[13579][26])0229

普通闰年:((0[48]|[2468][048]|[3579][26])00)0229

用 | 将其联系起来成为一条正则表达式,如下:

(((\d{2})(0[48]|[2468][048]|[13579][26])|((0[48]|[2468][048]|[3579][26])00))0229)

3.2 其他情况

现在解决了 2月29日 这个棘手的问题,对于其他日子,我们将不在区分闰年。看到这你是不是以为就可以直接 \d{4} 来表示y1y2y3y4 了?

看来你忽略了一个条件,在 2.2.1 中我们明确了时间的范围为为 0001010199991231 ,但当 y1y2y3y4\d{4} 存在 0000 这个情况,显然这个数据并不在我们合法的范围中。
因此我们可以得到如下的表:

y1y2y3y4
\d\d\d[1-9]
\d\d[1-9]\d
\d[1-9]\d\d
[1-9]\d\d\d

用 | 将其联系起来成为一条正则表达式,如下:

(\d{3}[1-9]|\d{2}[1-9]\d|\d[1-9]\d{2}|[1-9]\d{3})

然后就是构造 的正则表达式了

3.2.1 大月

首先是大月为:01,03,05,07,08,10,12。
正则表达式如下:

(0[13578]|1[02])

大月每月的日子从1日-31日均有。
正则表达式如下:

(0[1-9]|[12]\d|3[01])

故大月的正则表达式为:

((0[13578]|1[02])(0[1-9]|[12]\d|3[01]))
3.2.2 小月

首先是小月为:02,04,06,09,11。(但2月的日子和其他小月不同,这里将排除掉2月)
正则表达式如下:

(0[469]|11)

小月(不含2月)每月的日子从1日-30日均有。
正则表达式如下:

(0[1-9]|[12]\d|30)

故小月(除2月)的正则表达式为:

(0[469]|11)(0[1-9]|[12]\d|30))
3.2.3 2月

因为前面我们已经特殊表示了2月29日,所以这里我们只需要考虑2月的1日到28日,正则表达式如下:

(02(0[1-9]|[1]\d|2[0-8])

3.3 完整表达式

现在我们将全年的年月日均表达出来了,我们将其用 | 联系起来可得如下正则表达式(不包含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 总结

经过前面的努力,我们得到了如下的两个表达式:

闰年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]))))

最终我们将这两个情况,用 | 联系起来,我们就得到了校验日期的正则表达式了!

((\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)
  • 3
    点赞
  • 37
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
### 回答1: 可以使用Java正则表达式校验日期格式是否正确。下面是一个使用正则表达式校验日期的示例代码: ```java import java.util.regex.*; public class DateValidator { public static boolean isValidDate(String date) { // 使用正则表达式匹配日期格式 String regex = "^\\d{4}-\\d{2}-\\d{2}$"; Pattern pattern = Pattern.compile(regex); Matcher matcher = pattern.matcher(date); // 如果匹配成功,则日期格式正确,返回true;否则返回false return matcher.matches(); } public static void main(String[] args) { String date1 = "2020-06-01"; String date2 = "2020/06/01"; System.out.println(date1 + " 是否为有效日期: " + isValidDate(date1)); System.out.println(date2 + " 是否为有效日期: " + isValidDate(date2)); } } ``` 上述代码中,使用`^\\d{4}-\\d{2}-\\d{2}$`正则表达式来匹配日期格式。其中,`^`表示匹配字符串的开始,`\\d{4}`表示匹配4个数字,`-`表示匹配`-`字符,`\\d{2}`表示匹配2个数字,`$`表示匹配字符串的结束。通过`Pattern.compile(regex)`编译正则表达式,并使用`matcher.matches()`方法匹配输入的日期。如果匹配成功,则返回true,否则返回false。 在`main`方法中,将需要校验日期作为参数传递给`isValidDate`方法进行校验,并打印校验结果。 ### 回答2: Java正则表达式可以用于校验日期格式是否合法。下面是一个示例的正则表达式校验日期格式: String regex = "^(\\d{4})-(0?[1-9]|1[0-2])-(0?[1-9]|[12][0-9]|3[01])$"; 其中,正则表达式的含义如下: ^ 表示匹配字符串的开始位置 \\d{4} 表示匹配四个数字,即年份 - 表示匹配年份和月份之间的连接符 (0?[1-9]|1[0-2]) 表示匹配月份,可以是01到09或者是10到12 - 表示匹配月份和日期之间的连接符 (0?[1-9]|[12][0-9]|3[01]) 表示匹配日期,可以是01到09、10到29或者是30到31 $ 表示匹配字符串的结束位置 要使用正则表达式进行日期校验,可以使用String类的matches方法,如下所示: String date = "2021-10-15"; boolean isValid = date.matches(regex); if (isValid) { System.out.println("日期格式合法"); } else { System.out.println("日期格式不合法"); } 以上代码中,我们传入要校验日期正则表达式,使用matches方法进行匹配,结果为true表示日期格式合法,结果为false表示日期格式不合法。 需要注意的是,这个正则表达式校验日期格式,不校验具体的合法日期。例如,它可以匹配到2021-02-29这样的日期,但实际上2021年并没有2月29日这一天。因此,在实际应用中,还需要结合日期类进行进一步的校验,以确保日期的合法性。 ### 回答3: Java中可以使用正则表达式校验日期。以下是一个示例代码: ```java import java.util.regex.Matcher; import java.util.regex.Pattern; public class DateValidator { private static final String DATE_PATTERN = "^\\d{4}-\\d{2}-\\d{2}$"; public static boolean validateDate(String date) { Pattern pattern = Pattern.compile(DATE_PATTERN); Matcher matcher = pattern.matcher(date); return matcher.matches(); } public static void main(String[] args) { String date1 = "2022-01-01"; String date2 = "2022/01/01"; if (validateDate(date1)) { System.out.println(date1 + "是一个有效的日期"); } else { System.out.println(date1 + "不是一个有效的日期"); } if (validateDate(date2)) { System.out.println(date2 + "是一个有效的日期"); } else { System.out.println(date2 + "不是一个有效的日期"); } } } ``` 上述代码中,使用了一个正则表达式`^\\d{4}-\\d{2}-\\d{2}$`来校验日期格式是否为`yyyy-MM-dd`的形式。`^`和`$`分别表示字符串的开始和结束。`\\d{4}`表示四个数字的年份,`\\d{2}`表示两个数字的月份和日期。整个正则表达式要求输入的日期必须是以`yyyy-MM-dd`的格式表示。在`validateDate`方法中,通过Pattern类和Matcher类来进行正则表达式的匹配和校验。在main方法中,我们分别测试了一个符合要求的日期`2022-01-01`和一个不符合要求的日期`2022/01/01`,并打印出了校验结果。 请注意,这只是一个简单示例,仅校验日期格式,而不是真正的日期有效性。在实际应用中,可能还需要考虑月份、日期的范围等更详细的校验规则。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值