二月日期小于30时函数未返回true的问题排查与修正
问题分析与修复
你的代码存在几个关键问题导致不符合预期:
- 字符串与数字的隐式转换隐患:
month、day、year都是从字符串截取的结果,直接进行数值比较虽部分场景可行,但复杂情况下容易出现意料外的逻辑错误。 - 错误的30天月份判断:
month == (4 || 6 || 9 || 11)等价于month == 4——逻辑或运算的结果是第一个真值4,导致6、9、11月的日期超限判断完全失效。 - 你提到的二月日期<30却返回false的情况,大概率是非闰年的二月29号触发了
(year % 4 !== 0 && month == 2 && day > 28)的条件,这是符合真实日期规则的;如果你的业务需求允许非闰年二月存在29号,可调整该判断逻辑。
修复后的代码
function checkDateOfBirth(idNumber) { // 转换为数字类型,避免字符串比较问题 const year = Number(idNumber.substring(0, 2)); const month = Number(idNumber.substring(2, 4)); const day = Number(idNumber.substring(4, 6)); const dateRegex = /^([12]\d{3}-(0[1-9]|1[0-2])-(0[1-9]|[12]\d|3[0-1]))$/; const cutOffDate = new Date().getFullYear() - 2000; // 补全前导零,确保日期格式符合正则要求 const formattedMonth = month.toString().padStart(2, '0'); const formattedDay = day.toString().padStart(2, '0'); const fullDate = `${year > cutOffDate ? "19" : "20"}${year.toString().padStart(2, '0')}-${formattedMonth}-${formattedDay}`; // 闰年判断(如需更精确可加入百年闰年规则:能被400整除才是闰年) const isLeapYear = year % 4 === 0; if ( day > 31 || month < 1 || month > 12 || // 严格的二月日期校验:闰年最多29天,非闰年最多28天 (month === 2 && ((isLeapYear && day > 29) || (!isLeapYear && day > 28))) || // 修复30天月份的判断逻辑 ([4, 6, 9, 11].includes(month) && day > 30) || !dateRegex.test(fullDate) ) { return false; } return true; }
针对你的需求调整
如果不需要严格的闰年校验,只要求二月日期<30就返回true,只需修改二月的判断条件:
将:
(month === 2 && ((isLeapYear && day > 29) || (!isLeapYear && day > 28))) ||
替换为:
(month === 2 && day > 29) ||
这样无论是否为闰年,只要二月日期≤29(即<30)就不会触发false,函数会返回true。
内容的提问来源于stack exchange,提问作者PalesaDev
相关产品推荐
相关产品推荐

