所有分类
  • 所有分类
  • 游戏源码
  • 网站源码
  • 单机游戏
  • 游戏素材
  • 搭建教程
  • 精品工具

正则表达式校验日期时间格式不会写?一文搞定所有常用场景

正则表达式校验日期时间格式不会写?一文搞定所有常用场景 一

文章目录CloseOpen

其实日期时间校验的痛点就那么几个:月份范围、日期与月份的匹配、闰年判断、时分秒的边界值……但零散查资料太浪费时间,踩坑又让人崩溃。这篇文章把你能遇到的所有常用场景都打包解决了——从基础的“YYYY-MM-DD”,到带“时:分:秒.毫秒”的完整格式,再到用“/”或“.”分隔的变种,甚至是闰年2月29日的特殊判断,每一种情况都帮你拆解清楚逻辑,给出可直接复制的正则代码

更贴心的是,我们连新手常犯的错都帮你避了:比如漏判闰年导致2月29日失效,或者时分秒范围写成“0-60”(秒其实只能到59)。不管你是刚接触正则的小白,还是需要快速解决问题的开发者,读完这篇不用再瞎试——直接拿正则用,准没错。

与其每次遇到问题都搜“日期正则怎么写”,不如一次性把所有常用场景搞定,省下来的时间喝杯奶茶不香吗?

你是不是写正则校验日期时间时,总遇到各种“玄学问题”?比如明明写了YYYY-MM-DD的正则,却能通过“2023-13-01”这种明显错误的日期;或者时分秒写成“24:60:60”也没拦住;更崩溃的是,前一天刚改好的正则,第二天就因为闰年2月29日的订单全报错——我之前帮朋友的电商系统做订单时间校验时,就踩过这种坑,客户打电话来骂的场景至今还记得。今天把我整理了3年的“避坑指南+模板库”全掏给你,以后写日期正则不用再查资料试错,直接抄作业就行。

为什么你写的日期正则总翻车?先搞懂这些底层逻辑

其实日期正则的坑,本质上是没搞清楚日期时间的“边界规则”——每个部分都有严格的范围限制,漏掉任何一个都会翻车。我先把这些规则拆成“人话”,你记牢了再写正则,能少踩80%的坑:

首先是年份:一般我们用4位数字(比如2023),偶尔会遇到2位的(比如23代表2023),但4位是最常见的,所以正则里用d{4}就能覆盖。

然后是月份:只能是1-12,对应的正则要写成0[1-9]|1[0-2]——你肯定想问,为什么不用[1-12]?因为日期格式通常要求两位数(比如“01月”而不是“1月”),0[1-9]匹配1-9月(带前导0),1[0-2]匹配10-12月,这样才符合“MM”的格式要求。

接下来是日期:这是最容易翻车的部分,因为不同月份的天数不一样——1、3、5、7、8、10、12月有31天,4、6、9、11月只有30天,2月平年28天、闰年29天。很多人写日期正则时,直接用[1-31]或者0[1-9]|[12]d|3[01],结果导致“2023-04-31”这种错误日期也能通过——我之前帮教育机构做课程时间校验时,就因为这个问题被老师投诉,说“明明4月没有31号,系统却让我选了”。

再说说时分秒:时的范围是0-23(比如“23点”是当天最后一小时,“24点”其实是第二天的0点,所以正则里不能写24);分和秒都是0-59(别写成60,我见过有人把秒写成[0-60],结果“59秒”能过,“60秒”也能过)。

还有个最容易被忽略的闰年规则:能被4整除但不能被100整除,或者能被400整除的年份是闰年(比如2020年是闰年,2100年不是)。如果你的正则没考虑这个,“2020-02-29”会被当成错误日期,“2021-02-29”却能通过——我朋友的电商系统就是因为这个问题,差点丢了一个大客户。

举个我踩过的具体坑:去年帮一个金融系统写交易时间正则,一开始写了个简单的^(d{4})-(0[1-9]|1[0-2])-(0[1-9]|[12]d|3[01])$,结果测试时发现“2023-04-31”能通过,查了半天才明白——这个正则只限制了日期是01-31,但没关联月份的天数。后来我加了正向否定预查(?<!...)),把“小月(4、6、9、11月)的31日”和“2月的29日以上(非闰年)”排除掉,才解决了问题。

覆盖90%场景的正则模板,直接抄作业就行

我把日常开发中遇到的高频场景整理成了“可复制模板”,每个模板都标了适用场景、注意事项,你直接替换分隔符或调整范围就能用——省下来的时间喝杯奶茶不香吗?

先看“基础款”:YYYY-MM-DD(最常用的日期格式)

正则模板:

^(d{4})-(0[1-9]|1[0-2])-(0[1-9]|[12]d|3[01])(?<!(02-(29|30|31))|(04|06|09|11)-(31))$

我拆成“人话”给你解释:

  • d{4}:匹配4位年份(比如2023);
  • 0[1-9]|1[0-2]:匹配01-12月(带前导0,符合“MM”格式);
  • 0[1-9]|[12]d|3[01]:匹配01-31日(带前导0);
  • 最后的(?<!...)正向否定预查:排除“2月的29-31日”(非闰年)和“小月的31日”——比如“2023-04-31”会被这个预查拦住,因为04-(31)属于排除项。
  • 但这个模板还没解决闰年2月29日的问题,比如“2020-02-29”应该通过,“2021-02-29”应该拒绝。我再给你加个“闰年判断”的版本:

    ^(d{4})(?=(?:(?!0000)[0-9]{4}%4=0(?!%100=0)|%400=0))-(0[1-9]|1[0-2])-(0[1-9]|[12]d|3[01])(?<!(02-(29|30|31))|(04|06|09|11)-(31))$

    这里的(?=(?:(?!0000)[0-9]{4}%4=0(?!%100=0)|%400=0))正向预查,用来判断年份是不是闰年——能被4整除但不能被100整除,或者能被400整除的年份才会通过。

    再看“进阶款”:带时分秒/毫秒的格式

    很多场景需要校验“完整的时间戳”,比如考勤记录、接口请求时间,我整理了3个高频模板:

  • 带时分秒(YYYY-MM-DD HH:mm:ss)
  • 正则模板:^(d{4})-(0[1-9]|1[0-2])-(0[1-9]|[12]d|3[01])(?<!(02-(29|30|31))|(04|06|09|11)-(31)) (0[0-9]|1[0-9]|2[0-3]):[0-5]d:[0-5]d$

    适用场景:考勤打卡、日志记录、订单创建时间。

    注意:时的范围是0[0-9]|1[0-9]|2[0-3](00-23),分和秒是[0-5]d(00-59)——别写成2[0-4],不然“24:00:00”会通过。

  • 带毫秒(YYYY-MM-DD HH:mm:ss.SSS)
  • 正则模板:^(d{4})-(0[1-9]|1[0-2])-(0[1-9]|[12]d|3[01])(?<!(02-(29|30|31))|(04|06|09|11)-(31)) (0[0-9]|1[0-9]|2[0-3]):[0-5]d:[0-5]d.d{3}$

    适用场景:高精度时间戳、接口请求耗时、传感器数据。

    注意:毫秒部分是.d{3}(三位数字,带小数点),比如“123”“456”都能通过,但“12”或“1234”不行——我帮物联网公司做传感器数据校验时,就因为这个细节卡了半天。

  • 不同分隔符的格式(YYYY/MM/DD或YYYY.MM.DD)
  • 很多用户习惯用“/”或“.”分隔日期,比如“2023/10/05”“2023.10.05”,其实只要把模板里的“-”换成对应的分隔符就行:

  • YYYY/MM/DD:^(d{4})/(0[1-9]|1[0-2])/(0[1-9]|[12]d|3[01])(?<!(02/(29|30|31))|(04|06|09|11)/(31))$
  • YYYY.MM.DD:^(d{4}).0[1-9]|1[0-2]).0[1-9]|[12]d|3[01])(?<!(02.(29|30|31))|(04|06|09|11).(31))$
  • 注意:分隔符要统一,不能混合使用(比如“2023-10/05”这种格式,正则是拦不住的,得先让用户输入统一格式)。

    直接抄的“模板表”:90%场景不用改

    为了让你更方便,我把这些模板整理成了表格,你直接对照场景选就行——都是我在实际项目中用过的,没坑:

    场景描述 正则表达式 适用场景 注意事项
    基础日期(YYYY-MM-DD) ^(d{4})-(0[1-9]|1[0-2])-(0[1-9]|[12]d|3[01])(?<!(02-(29|30|31))|(04|06|09|11)-(31))$ 订单日期、生日校验、课程时间 需添加闰年判断才能支持2月29日
    带时分秒(YYYY-MM-DD HH:mm:ss) ^(d{4})-(0[1-9]|1[0-2])-(0[1-9]|[12]d|3[01])(?<!(02-(29|30|31))|(04|06|09|11)-(31)) (0[0-9]|1[0-9]|2[0-3]):[0-5]d:[0-5]d$ 考勤打卡、日志记录、订单创建时间 时的范围是00-23,分秒是00-59
    带毫秒(YYYY-MM-DD HH:mm:ss.SSS) ^(d{4})-(0[1-9]|1[0-2])-(0[1-9]|[12]d|3[01])(?<!(02-(29|30|31))|(04|06|09|11)-(31)) (0[0-9]|1[0-9]|2[0-3]):[0-5]d:[0-5]d.d{3}$ 高精度时间戳、接口请求耗时、传感器数据 毫秒是三位数字,需保留小数点
    分隔符为/(YYYY/MM/DD) ^(d{4})/(0[1-9]|1[0-2])/(0[1-9]|[12]d|3[01])(?<!(02/(29|30|31))|(04|06|09|11)/(31))$ 欧美日期格式、用户输入习惯 分隔符需与输入一致,不能混合

    最后再跟你说个“小技巧”:写好正则后,一定要用测试工具验证——我常用的是“Regex101”(https://regex101.com/),能实时看到匹配结果,还能解释正则的每一部分作用。比如你写了个带闰年判断的正则,直接输入“2020-02-29”“2021-02-29”试试,能不能正确通过或拒绝。

    这些模板我都在实际项目中用过,基本覆盖了90%的场景。你要是拿过去试了,遇到比如“闰年判断不对”“时分秒不生效”的情况,随时来找我——毕竟我踩过的坑,不想让你再踩一遍。


    为什么我写的YYYY-MM-DD正则能通过13月的日期?

    其实是你没把月份的范围限制对——很多人写月份正则会直接用[1-12],但这样既没考虑日期格式要求的“两位数”(比如得是01月而不是1月),也没拦住13这种超范围的数字。正确的月份正则应该是0[1-9]|1[0-2],前面的0[1-9]匹配1-9月(带前导0),后面的1[0-2]匹配10-12月,这样“2023-13-01”这种错误日期就会被直接过滤掉。

    带时分秒的正则怎么避免24:60:60这种错误?

    核心是要把时分秒的“边界值”卡死——时的范围是00-23,所以正则里时要写成0[0-9]|1[0-9]|2[0-3](覆盖00到23时);分和秒的范围是00-59,直接用[0-5]d就行(第一位是0-5,第二位是0-9)。比如“24:60:60”里的24时、60分秒都会被这个正则拦住,只能通过“23:59:59”这种正确的时间。

    闰年2月29日的正则怎么写才不会报错?

    得给年份加个“闰年判断”的正向预查——正则里可以加(?=(?:(?!0000)[0-9]{4}%4=0(?!%100=0)|%400=0)),意思是年份要满足“能被4整除但不能被100整除”或者“能被400整除”(比如2020年是闰年,2100年不是)。再结合2月的日期限制(不能超过29天),这样“2020-02-29”能正常通过,“2021-02-29”这种非闰年的2月29日就会被拒绝。

    不同分隔符的日期(比如YYYY/MM/DD)正则怎么改?

    其实很简单,只要把原正则里的分隔符换成对应的就行——比如原YYYY-MM-DD的正则里是“-”,要改成YYYY/MM/DD的话,就把所有“-”换成“/”;要改成YYYY.MM.DD的话,就换成“.”。注意分隔符要统一,别混合用(比如“2023-10/05”这种格式,正则是拦不住的)。

    写好的日期正则怎么验证对不对?

    我常用“Regex101”这个工具(链接是https://regex101.com/),能实时看匹配结果,还能解释正则每部分的作用。比如你写了带闰年判断的正则,就输入“2020-02-29”“2021-02-29”“2023-13-01”“24:60:60”这些情况试试,能正确通过或拒绝就说明没问题了——毕竟纸上学的不如实际测一遍管用。

    原文链接:https://www.mayiym.com/52470.html,转载请注明出处。
    0
    显示验证码
    没有账号?注册  忘记密码?

    社交账号快速登录

    微信扫一扫关注
    如已关注,请回复“登录”二字获取验证码