You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.21 07:37:53