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

Node.js中Joi校验:限制endDate不晚于startDate后3年的问题

解决Joi校验endDate不得晚于startDate后3年的问题

你尝试用两种写法限制endDate不超过startDate之后3年,但都触发错误,提示endDate必须小于等于startDate本身,报错信息如下:

"message": "\"endDate\"必须小于等于\"Fri Mar 29 2024 03:00:00 GMT+0300\""

原写法问题分析

  • 第一种写法通过getTime()计算毫秒数后返回数字,但Joi的date().max()期望接收Date对象或符合格式的日期值,而非时间戳,导致校验逻辑异常。
  • 第二种写法的adjust: ['+3 years']格式不符合Joi规范,Joi.ref的adjust参数不支持这种数组形式的调整指令。

正确写法示例

写法一:修正ref的adjust函数返回Date对象

直接操作Date对象并返回,确保Joi能正确识别最大日期值,同时避免手动计算毫秒数的闰年误差:

const maxEndDate = Joi.ref('startDate', {
  adjust: (startDate) => {
    const adjustedDate = new Date(startDate);
    adjustedDate.setFullYear(adjustedDate.getFullYear() + 3);
    return adjustedDate;
  }
});

const validate = {
  query: {
    startDate: Joi.date().format(DATE_FORMAT).utc().required(),
    endDate: Joi.date()
      .format(DATE_FORMAT)
      .utc()
      .min(Joi.ref('startDate'))
      .max(maxEndDate)
      .raw()
      .required(),
  }
};

写法二:使用自定义校验逻辑

自定义校验更直观可控,还能自定义报错提示:

const validate = {
  query: {
    startDate: Joi.date().format(DATE_FORMAT).utc().required(),
    endDate: Joi.date()
      .format(DATE_FORMAT)
      .utc()
      .min(Joi.ref('startDate'))
      .custom((endDate, helpers) => {
        const { startDate } = helpers.state.ancestors[0];
        const maxAllowedDate = new Date(startDate);
        maxAllowedDate.setFullYear(maxAllowedDate.getFullYear() + 3);
        
        if (endDate > maxAllowedDate) {
          return helpers.error('date.max', { limit: maxAllowedDate });
        }
        return endDate;
      })
      .messages({
        'date.max': '"endDate"不得晚于startDate之后3年,最大允许日期为{{limit}}'
      })
      .raw()
      .required(),
  }
};

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 15:07:26