使用day.js解析无年份日期时如何检测原输入未携带年份
有两种可靠性更高的实现方案,具体如下:
方案1:使用CustomParseFormat插件严格匹配格式(最推荐)
dayjs官方提供的CustomParseFormat插件支持严格模式解析,你只需提前梳理业务中允许的所有日期格式,按「无年份」「带年份」分组匹配即可,完全不受dayjs默认补全规则的影响,准确性最高。
用法示例
import dayjs from 'dayjs' import CustomParseFormat from 'dayjs/plugin/customParseFormat.js' // 按需引入多语言包 import 'dayjs/locale/zh-cn.js' dayjs.extend(CustomParseFormat) // 按无年份、带年份分组定义业务支持的所有格式 // 多语言格式可对应扩展,比如中文的「M月D日」、英文的「D MMM」等 const DATE_FORMATS = { NO_YEAR: ['MM-DD', 'M/D', 'D MMM', 'D MMMM', 'M月D日'], WITH_YEAR: ['YYYY-MM-DD', 'YYYY/M/D', 'D MMM YYYY', 'YYYY年M月D日'] } function checkDateHasYear(dateStr, locale = 'en') { // 先尝试匹配无年份格式,严格模式开启后格式不匹配直接返回无效日期 const parseNoYearRes = dayjs(dateStr, DATE_FORMATS.NO_YEAR, locale, true) if (parseNoYearRes.isValid()) { return false } // 再尝试匹配带年份格式 const parseWithYearRes = dayjs(dateStr, DATE_FORMATS.WITH_YEAR, locale, true) if (parseWithYearRes.isValid()) { return true } // 格式均不匹配可按业务需求处理,比如抛出异常 throw new Error('输入的日期格式不合法') } // 测试 console.log(checkDateHasYear('06-05')) // false console.log(checkDateHasYear('5 June')) // false console.log(checkDateHasYear('2023-06-05')) // true console.log(checkDateHasYear('2023年6月5日', 'zh-cn')) // true
优缺点
- 优点:准确性100%,完全不依赖dayjs内部默认规则,同时可以校验输入日期的合法性,适配多语言场景成本低
- 缺点:需要提前梳理业务允许的所有日期格式,适合格式范围可控的业务场景
方案2:双年份对照校验(适配未知格式场景)
如果业务允许的日期格式不固定无法枚举,可以用对照法判断:分别用两套不同的默认补全年份规则解析同一个输入,如果两次解析得到的年份一致,说明输入本身携带年份,反之则是dayjs自动补全的年份。
用法示例
import dayjs from 'dayjs' function checkDateHasYear(dateStr) { // 第一次用默认规则解析拿到年份 const defaultYear = dayjs(dateStr).year() // 第二次解析时,强制替换默认补全的年份为1970 const customParseDate = new Date(dateStr) if (customParseDate.getFullYear() === 2001 && !dateStr.includes('2001')) { customParseDate.setFullYear(1970) } const customYear = dayjs(customParseDate).year() // 两次年份一致说明输入自带年份,否则是自动补全 return defaultYear === customYear } // 测试 console.log(checkDateHasYear('06-05')) // false console.log(checkDateHasYear('6/5')) // false console.log(checkDateHasYear('2001-06-05')) // true console.log(checkDateHasYear('2020-06-05')) // true
优缺点
- 优点:不需要提前枚举格式,适配性更强
- 缺点:需要处理输入刚好携带2001年的边界场景,依赖当前dayjs调用原生Date解析的规则
内容的提问来源于stack exchange,提问作者Graham Charles
相关产品推荐
相关产品推荐

