是的,将最小最大日期与构建日期而不是当前日期进行比较
Yup compares min max date with build date instead of current date
所以这很奇怪,我无法理解它的来源。
我有一个注册 WS(在 Node.js 中使用 Sales.js),其中最低要求年龄为 18 岁,验证由 Yup 完成。
这是我的 yup 模式:
const yup = require('yup');
const moment = require('moment');
const birthdate = yup.date()
.typeError('INVALID_DATE')
.min(moment().subtract(115, 'years'), 'MIN_AGE')
.max(moment().endOf('day').subtract(18, 'years'), 'MAX_AGE');
module.exports = {
birthdate
};
正如您从下面的示例中看到的那样,当我输入今天的日期时,它将它与 2002-07-31
进行比较,而它应该与 moment().endOf('day').subtract(18, 'years')
进行比较,后者应该是 2002-08-12
请注意,2002-07-31
是我构建项目的日期。所以如果我现在重新编译它,我今天将不再有这个问题。如果我明天重新测试,它将与今天的日期进行比较!
我不知道这怎么可能或如何解决它。
这是来自 yup 的错误:
"errors": [{
"field": "birthdate",
"code": "E_MAX_AGE_BIRTHDATE",
"params": {
"path": "birthdate",
"value": "2002-08-12T10:00:00.000Z",
"originalValue": "2002-08-12T10:00:00.000Z",
"max": "2002-07-31T21:59:59.999Z"
}
}]
有什么想法吗?
使用的版本:moment 2.24.0
; yup 0.29.2
好的,所以我找到了解决方案。
事实上,Yup 会存储您最初提供的日期并进行编译。它将不再在您每次验证日期时执行 moment().endOf('day').subtract(18, 'years')
。
为此,您必须使用测试方法,而不是 min
或 max
。
我已经为 yup.date
创建了一个扩展方法,如下所示:
/**
* This function is used to format the error like date.min does
*/
function customValidationError(errorMessage, value, path, extraData) {
const error = new yup.ValidationError(errorMessage,
value,
path);
error.params = {
path: path,
value: value,
originalValue: value,
...extraData
};
return error;
}
/**
* Extension method to yup.date
* You should pass a function that will be executed each time you want to check again the current date.
* @name yup.dynamicMaxDate
* @global yup.dynamicMaxDate
*/
yup.addMethod(yup.date, 'dynamicMaxDate', function(path, errorMessage = 'MAX_DATE', maxDateFunction) {
return this.test(path, errorMessage,
(value) => {
const maxDate = maxDateFunction();
return new Promise((resolve, reject) => {
const error = customValidationError(errorMessage, value, path, {
max: maxDate
});
value && moment(value).isAfter(maxDate) ?
reject(error) :
resolve(true);
});
});
});
/**
* Extension method to yup.date to check if date is before a given date
* You should pass a function that will be executed each time you want to check again the current date.
* @name yup.dynamicMinDate
* @global yup.dynamicMinDate
*/
yup.addMethod(yup.date, 'dynamicMinDate', function(path, errorMessage = 'MIN_DATE', minDateFunction) {
return this.test(path, errorMessage,
(value) => {
const minDate = minDateFunction();
return new Promise((resolve, reject) => {
const error = customValidationError(errorMessage, value, path, {
min: minDate
});
value && moment(value).isBefore(minDate) ?
reject(error) :
resolve(true);
});
});
});
并使用这些方法:
const birthdate = yup.date()
.typeError('INVALID_DATE')
// Note tham I'm passing a function to be executed when validating date
.dynamicMinDate('birthdate', 'MIN_AGE', () => {
return moment().startOf('day').subtract(115, 'years').toDate();
})
.dynamicMaxDate('birthdate', 'MAX_AGE', () => {
return moment().endOf('day').subtract(18, 'years').toDate();
});
所以这很奇怪,我无法理解它的来源。
我有一个注册 WS(在 Node.js 中使用 Sales.js),其中最低要求年龄为 18 岁,验证由 Yup 完成。
这是我的 yup 模式:
const yup = require('yup');
const moment = require('moment');
const birthdate = yup.date()
.typeError('INVALID_DATE')
.min(moment().subtract(115, 'years'), 'MIN_AGE')
.max(moment().endOf('day').subtract(18, 'years'), 'MAX_AGE');
module.exports = {
birthdate
};
正如您从下面的示例中看到的那样,当我输入今天的日期时,它将它与 2002-07-31
进行比较,而它应该与 moment().endOf('day').subtract(18, 'years')
进行比较,后者应该是 2002-08-12
请注意,2002-07-31
是我构建项目的日期。所以如果我现在重新编译它,我今天将不再有这个问题。如果我明天重新测试,它将与今天的日期进行比较!
我不知道这怎么可能或如何解决它。
这是来自 yup 的错误:
"errors": [{
"field": "birthdate",
"code": "E_MAX_AGE_BIRTHDATE",
"params": {
"path": "birthdate",
"value": "2002-08-12T10:00:00.000Z",
"originalValue": "2002-08-12T10:00:00.000Z",
"max": "2002-07-31T21:59:59.999Z"
}
}]
有什么想法吗?
使用的版本:moment 2.24.0
; yup 0.29.2
好的,所以我找到了解决方案。
事实上,Yup 会存储您最初提供的日期并进行编译。它将不再在您每次验证日期时执行 moment().endOf('day').subtract(18, 'years')
。
为此,您必须使用测试方法,而不是 min
或 max
。
我已经为 yup.date
创建了一个扩展方法,如下所示:
/**
* This function is used to format the error like date.min does
*/
function customValidationError(errorMessage, value, path, extraData) {
const error = new yup.ValidationError(errorMessage,
value,
path);
error.params = {
path: path,
value: value,
originalValue: value,
...extraData
};
return error;
}
/**
* Extension method to yup.date
* You should pass a function that will be executed each time you want to check again the current date.
* @name yup.dynamicMaxDate
* @global yup.dynamicMaxDate
*/
yup.addMethod(yup.date, 'dynamicMaxDate', function(path, errorMessage = 'MAX_DATE', maxDateFunction) {
return this.test(path, errorMessage,
(value) => {
const maxDate = maxDateFunction();
return new Promise((resolve, reject) => {
const error = customValidationError(errorMessage, value, path, {
max: maxDate
});
value && moment(value).isAfter(maxDate) ?
reject(error) :
resolve(true);
});
});
});
/**
* Extension method to yup.date to check if date is before a given date
* You should pass a function that will be executed each time you want to check again the current date.
* @name yup.dynamicMinDate
* @global yup.dynamicMinDate
*/
yup.addMethod(yup.date, 'dynamicMinDate', function(path, errorMessage = 'MIN_DATE', minDateFunction) {
return this.test(path, errorMessage,
(value) => {
const minDate = minDateFunction();
return new Promise((resolve, reject) => {
const error = customValidationError(errorMessage, value, path, {
min: minDate
});
value && moment(value).isBefore(minDate) ?
reject(error) :
resolve(true);
});
});
});
并使用这些方法:
const birthdate = yup.date()
.typeError('INVALID_DATE')
// Note tham I'm passing a function to be executed when validating date
.dynamicMinDate('birthdate', 'MIN_AGE', () => {
return moment().startOf('day').subtract(115, 'years').toDate();
})
.dynamicMaxDate('birthdate', 'MAX_AGE', () => {
return moment().endOf('day').subtract(18, 'years').toDate();
});