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

如何在Yup中校验日期是否符合指定格式?

问题:用Yup校验日期时如何强制指定格式?

我现在用Yup校验日期输入字段,代码如下:

const dateToCheck = yup
    .date()
    .nullable()
    .transform((curr, orig) => (orig === '' ? null : curr))
    .required()
    .min(minDate, 'Date cannot be this early')
    .max(maxDate, 'Date too much in the future')
    .test('format', 'Date is invalid', date => (date?.getFullYear() ?? 0) <= 9999)

现在的问题是,Yup的date()方法会自动识别多种格式(比如01.01.2000和2000/01/01都能通过校验),但我需要仅允许特定格式通过——要么只接受dd.MM.yyyy,要么只接受yyyy/MM/dd,其他格式都标记为无效。请问在Yup里怎么实现这个需求?


解决方案

核心思路是:不要依赖Yup自动解析日期,而是先通过正则校验原始输入字符串的格式,再手动将其转换为合法的Date对象(格式不匹配时返回无效值)。

情况1:强制要求dd.MM.yyyy格式

修改校验规则,加入正则校验和自定义转换逻辑:

const dateToCheck = yup
  .string() // 先将字段视为字符串,方便直接校验原始格式
  .nullable()
  .transform((curr, orig) => orig === '' ? null : curr)
  .required('Date is required')
  // 第一步:用正则匹配dd.MM.yyyy格式
  .matches(/^\d{2}\.\d{2}\.\d{4}$/, 'Date must be in dd.MM.yyyy format')
  // 第二步:验证日期实际合法性(比如排除2月30号这类格式正确但逻辑错误的日期)
  .test('valid-date', 'Invalid date', value => {
    if (!value) return true;
    const [day, month, year] = value.split('.').map(Number);
    const date = new Date(year, month - 1, day);
    // 确保转换后的日期与原始输入的日/月/年完全匹配
    return date.getFullYear() === year && date.getMonth() === month - 1 && date.getDate() === day;
  })
  // 第三步:将合法字符串转换为Date对象,供后续min/max校验使用
  .transform((value) => {
    if (!value) return null;
    const [day, month, year] = value.split('.').map(Number);
    return new Date(year, month - 1, day);
  })
  .min(minDate, 'Date cannot be this early')
  .max(maxDate, 'Date too much in the future');

情况2:强制要求yyyy/MM/dd格式

调整正则和转换逻辑即可:

const dateToCheck = yup
  .string()
  .nullable()
  .transform((curr, orig) => orig === '' ? null : curr)
  .required('Date is required')
  .matches(/^\d{4}\/\d{2}\/\d{2}$/, 'Date must be in yyyy/MM/dd format')
  .test('valid-date', 'Invalid date', value => {
    if (!value) return true;
    const [year, month, day] = value.split('/').map(Number);
    const date = new Date(year, month - 1, day);
    return date.getFullYear() === year && date.getMonth() === month - 1 && date.getDate() === day;
  })
  .transform((value) => {
    if (!value) return null;
    const [year, month, day] = value.split('/').map(Number);
    return new Date(year, month - 1, day);
  })
  .min(minDate, 'Date cannot be this early')
  .max(maxDate, 'Date too much in the future');

关键说明

  • 将字段从date()改为string(),直接校验原始输入的格式,避免Yup自动兼容多种日期字符串。
  • matches()方法用来做格式的正则校验,直接返回格式错误提示。
  • 额外的test()方法用于过滤格式正确但实际无效的日期。
  • 最后通过transform()将合法字符串转为Date对象,保证后续的min()/max()校验能正常运行。

内容的提问来源于stack exchange,提问作者Alex T

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 17:31:07