求适配dd/mm/yyyy与mm/dd/yyyy的有效日期正则(年份≤3000)
适配dd/mm/yyyy与mm/dd/yyyy的有效日期正则方案
直接上符合需求的正则表达式,同时附详细拆解和使用示例:
const validDateRegex = /^(?:(?:(0[13578]|1[02])\/(0[1-9]|[12]\d|3[01])|(0[469]|11)\/(0[1-9]|[12]\d|30)|02\/(0[1-9]|[12]\d))\/(?:1\d{3}|2\d{3}|3000)|(?:(0[1-9]|[12]\d|3[01])\/(0[13578]|1[02])|(0[1-9]|[12]\d|30)\/(0[469]|11)|(0[1-9]|[12]\d)\/02)\/(?:1\d{3}|2\d{3}|3000)|(?:02\/29|29\/02)\/(?:(?:1[6-9]|2\d)\d{2}(?:0[48]|[2468][048]|[13579][26])|2000|1600))$/;
正则逻辑拆解
这个正则通过三个分支覆盖所有合法情况,用|分隔:
1. 非闰年的dd/mm/yyyy格式
匹配31天月份、30天月份、平年2月的合法日期,年份限制在1000-3000:
(0[13578]|1[02]):匹配1、3、5、7、8、10、12月(两位数格式)(0[1-9]|[12]\d|3[01]):对应31天月份的日期(01-31)(0[469]|11):匹配4、6、9、11月(0[1-9]|[12]\d|30):对应30天月份的日期(01-30)02\/(0[1-9]|[12]\d):匹配平年2月的日期(01-28)(?:1\d{3}|2\d{3}|3000):匹配1000-2999或3000的四位数年份
2. 非闰年的mm/dd/yyyy格式
和第一分支逻辑完全一致,只是把月份和日期的位置互换,适配mm/dd/yyyy格式
3. 闰年2月29日的两种格式
单独处理闰年2月29日的特殊情况,严格遵循闰年规则:
(?:02\/29|29\/02):同时匹配dd/mm和mm/dd格式的2月29日- 年份部分:
(?:1[6-9]|2\d)\d{2}:覆盖1600-2999的年份范围(0[48]|[2468][048]|[13579][26]):匹配能被4整除但非整百年的年份(比如2020、2024)2000|1600:匹配能被400整除的整百年(这两个是符合闰年规则的整百年份)
使用示例
// 测试合法日期 console.log(validDateRegex.test('31/12/2999')); // true (dd/mm/yyyy) console.log(validDateRegex.test('12/31/2999')); // true (mm/dd/yyyy) console.log(validDateRegex.test('29/02/2000')); // true (闰年 dd/mm) console.log(validDateRegex.test('02/29/2000')); // true (闰年 mm/dd) console.log(validDateRegex.test('28/02/2023')); // true (平年 dd/mm) // 测试非法日期 console.log(validDateRegex.test('31/04/2023')); // false (4月无31天) console.log(validDateRegex.test('29/02/2023')); // false (2023非闰年) console.log(validDateRegex.test('99/99/9999')); // false (无效月日) console.log(validDateRegex.test('10/10/3001')); // false (年份超3000)
注意事项
- 该正则仅校验格式和日期有效性,无法区分
01/02/2023是1月2日还是2月1日,若需区分格式,需额外添加业务逻辑判断。 - 正则使用非捕获组
(?:...)减少不必要的分组捕获,提升匹配性能。
内容的提问来源于stack exchange,提问作者Roza
相关产品推荐
相关产品推荐

