Joi日期参数验证报错:如何实现起止日期间隔不超30天?
Joi日期参数验证:startDate与endDate间隔不超过30天的正确写法
你之前的写法错误在于直接对Joi.ref('startDate')进行数值运算,Joi的引用对象不支持这种操作,必须通过Joi提供的日期调整方法或自定义验证逻辑来实现时间间隔限制。以下是两种可行的正确写法:
方法一:使用ref的adjust回调(推荐)
利用Joi.ref的adjust回调函数,动态计算startDate加上30天后的日期,再用max规则限制endDate不超过该日期:
const Joi = require('joi'); const dateSchema = Joi.object({ startDate: Joi.date().default(() => new Date()), // 用函数返回当前时间,避免固定默认值 endDate: Joi.date() .default(() => new Date()) .max(Joi.ref('startDate', { adjust: (startDate) => new Date(startDate.getTime() + 30 * 24 * 60 * 60 * 1000) })) .min(Joi.ref('startDate')) // 可选:确保endDate不早于startDate });
方法二:自定义验证函数(更灵活)
通过custom方法编写自定义逻辑,直接计算两个日期的时间差并验证:
const Joi = require('joi'); const dateSchema = Joi.object({ startDate: Joi.date().default(() => new Date()), endDate: Joi.date() .default(() => new Date()) .custom((endDate, helpers) => { const startDate = helpers.state.ancestors[0].startDate; const timeDiff = endDate.getTime() - startDate.getTime(); const maxAllowedDiff = 30 * 24 * 60 * 60 * 1000; // 30天对应的毫秒数 if (timeDiff > maxAllowedDiff) { return helpers.error('custom.date.max', { limit: '30天' }); } if (timeDiff < 0) { return helpers.error('custom.date.min'); } return endDate; }) }); // 自定义错误信息示例 const validationResult = dateSchema.validate( { startDate: new Date(), endDate: new Date(Date.now() + 31 * 24 * 60 * 60 * 1000) }, { messages: { 'custom.date.max': 'endDate 不能比 startDate 晚超过{{limit}}', 'custom.date.min': 'endDate 不能早于 startDate' } } );
注意事项
- 用
() => new Date()作为默认值:避免在schema定义时就生成固定日期,确保每次验证都使用当前时间作为默认值。 - 若不需要限制endDate不早于startDate,可以去掉
.min(Joi.ref('startDate'))规则。
内容的提问来源于stack exchange,提问作者reis12341
相关产品推荐
相关产品推荐

