MUI X DateField中AdapterDateFns闰年验证过早触发的配置问题
适配MUI X DateField的AdapterDateFns闰年输入行为配置
在@mui/x-date-pickers 6.4.0版本中,使用DateField输入2月29日(有效闰年日期)时,AdapterDateFns会在输入年份第一个字符后自动将日期回退到2月28日(推测是将未完成输入的年份识别为0001年,非闰年),而AdapterDayjs则会保留2月29日直到完整四位年份输入完成。要让AdapterDateFns实现和AdapterDayjs一致的行为,可以通过以下方案调整:
自定义日期解析逻辑
重写AdapterDateFns的parse和format方法,在年份未完全输入时暂时跳过严格闰年校验,用临时闰年年份解析以保留输入的日期值,待年份完整后再执行正常校验。示例代码:import { AdapterDateFns } from '@mui/x-date-pickers/AdapterDateFns'; import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { DateField } from '@mui/x-date-pickers/DateField'; import parse from 'date-fns/parse'; import isValid from 'date-fns/isValid'; import format from 'date-fns/format'; const CustomAdapterDateFns = { ...AdapterDateFns, parse: (value: string, formatString: string) => { const parts = value.split('/'); // 针对DD/MM/YYYY格式,判断年份输入是否完整 if (parts.length === 3 && parts[2].length < 4) { // 用临时闰年2000年解析,避免日期被回退 const tempValue = `${parts[0]}/${parts[1]}/2000`; const tempDate = parse(tempValue, formatString, new Date()); // 存储用户输入的原始年份片段 return { ...tempDate, __rawYear: parts[2] } as unknown as Date; } // 年份完整时使用原解析逻辑 const date = parse(value, formatString, new Date()); return isValid(date) ? date : null; }, format: (date: any, formatString: string) => { if (date.__rawYear) { // 替换临时年份为用户输入的原始片段 const formatted = format(date, formatString); return formatted.replace('2000', date.__rawYear); } return format(date, formatString); } }; export default function CustomDateField() { return ( <LocalizationProvider dateAdapter={CustomAdapterDateFns}> <DateField format="dd/MM/yyyy" /> </LocalizationProvider> ); }延迟校验触发时机
通过disableInvalidation关闭自动校验,在onChange中手动控制校验逻辑,仅当年份输入完整后再验证日期有效性:<DateField format="dd/MM/yyyy" disableInvalidation={true} onChange={(newValue) => { if (!newValue) return; const yearStr = newValue.getFullYear().toString(); // 仅当年份为完整四位时执行闰年校验 if (yearStr.length === 4 && !isValid(newValue)) { alert('请输入有效的闰年日期'); } }} />启用date-fns宽松解析
在parse时传入strict: false选项,允许宽松解析未完成的日期,避免过早触发日期修正:// 在自定义适配器的parse方法中修改 const date = parse(value, formatString, new Date(), { strict: false });
内容的提问来源于stack exchange,提问作者Rob74
相关产品推荐
相关产品推荐

