使用express validator校验生日时遇异常问题求助
生日校验代码的异常问题排查
问题描述
我用于校验生日的代码如下:
check('birthday').isDate({format:"YYYY-MM-DD"}).custom((value)=>{ var dob = new Date(value) var year = dob.getFullYear() var today = new Date(); var age = today.getFullYear() - year if (age < 18){ throw new Error('Your age should be 18+') } })
当输入未满18岁的生日时,能正常弹出错误提示Your age should be 18+;但输入2000-06-05这类符合格式的成年日期时,却返回如下错误:
{"errors":[{"value":"2000-06-05","msg":"Invalid value","param":"birthday","location":"body"}]}
请问该问题的原因是什么?
问题原因及修复方案
核心原因
问题出在isDate校验的格式参数上。你使用的校验库(比如express-validator)中,isDate方法的格式占位符区分大小写:
- 小写
yyyy代表常规公历年份 - 大写
YYYY代表ISO周编号对应的年份(和普通公历年份规则不一致)
你传入的格式是YYYY-MM-DD,库无法按这个规则解析2000-06-05这类常规日期,直接判定为无效值,跳过了后续的自定义年龄校验,返回Invalid value错误。
修复步骤
- 调整格式字符串为
yyyy-MM-dd,让库能正确解析常规日期:
check('birthday').isDate({format:"yyyy-MM-dd"}).custom((value)=>{ var dob = new Date(value) var today = new Date(); var age = today.getFullYear() - dob.getFullYear(); // 补充:修正年龄计算漏洞,避免“年份满18但未到生日”的情况 const monthDiff = today.getMonth() - dob.getMonth(); if (monthDiff < 0 || (monthDiff === 0 && today.getDate() < dob.getDate())) { age--; } if (age < 18){ throw new Error('Your age should be 18+') } })
- 额外优化:原代码的年龄计算仅对比年份差,忽略了月份和日期。比如今天是2024年5月10日,用户生日是2006年6月15日,年份差为18,但实际未到生日,年龄应为17岁。上述代码补上了该逻辑,保证校验准确性。
内容的提问来源于stack exchange,提问作者Aayushi Vaghasiya
相关产品推荐
相关产品推荐

