I have to add validation for card expiry where I need to show an error message if the card is about to expire within 3 month's from current date
ex:
(month/year)1221 input --> false (invalid)
1121 input --> false (invalid)
122 input --> false (invalid)
221 input --> true (valid)
222 input --> true (valid)
From the backend this is the value I am getting value = 424 --> 4 is the month and 24 is the year which is valid and if from backend I am getting 1121 ---> 11 is the month and 21 is the year which is invalid
How to validate if the date 1121 is within 3 months?
Below is the solution I am using but I don't find other solutions
const d = new Date();
let today = d.getDate();
expValue = 424;
const originalValue = expValue.toString().split(/(?=(?:.{2}) $)/g);
if (
originalValue[0] >= today.month.toString() 3 ||
originalValue[1] === today.year.toString()
) {
return this.sanitizer.bypassSecurityTrustHtml(
'<span >'
('0' originalValue[0]).slice(-2)
'/'
originalValue[1]
'</span>'
);
} else {
return this.sanitizer.bypassSecurityTrustHtml(
('0' originalValue[0]).slice(-2) '/' originalValue[1]
);
}
}
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
CodePudding user response:
Using the original inputs you gave, you can do something like this:
let inputs = ['12/21', '11/21', '01/22', '02/21', '12/22'];
const parseDate =(e)=>{ return new Date(e.replace('/', '/1/')); };
const getDiff = (e)=>{
let curr = new Date();
let dt = parseDate(e);
return (dt.getMonth() - curr.getMonth()
(12 * (dt.getYear() - curr.getYear()))) > 3;
}
inputs.forEach(el=>console.log(`${el} >> ${getDiff(el)}`));
<iframe name="sif2" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
If your inputs are in a different format or if you have to account for strings that aren't always the same length you might have to adjust the parseDate function. If you are working with a variable length string without the included "/", then you might try something like this, using the new inputs you gave:
let inputs = ['1221', '1121', '122', '221', '222'];
const parseDate =(e)=>{
if(e.length==3) { e = '0' e; }
return new Date(`${e.substring(0,2)}/1/${e.slice(-2)}`);
};
const getDiff = (e)=>{
let curr = new Date();
let dt = parseDate(e);
return (dt.getMonth() - curr.getMonth()
(12 * (dt.getYear() - curr.getYear()))) > 3;
}
inputs.forEach(el=>console.log(`${el} >> ${getDiff(el)}`));
<iframe name="sif3" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
I modify the parseDate function to pad the string if the length is 3 (I think it's always going to be 3 or 4), then create a date from the first two characters and the last two characters, then return that, and everything else is the same.
CodePudding user response:
I think the best way to go at this is to translate dates into units that are suited to the problem. JS date getYear()
gives months since 1990, and that's a practically useful common unit.
Put the input string date and the current date into units of months since 1990, then compare...
const monthsSince1900 = string => {
let chars = string.split('');
let month = chars.slice(0, -2).join('');
let year = chars.slice(-2).join('');
return 12 * (100 year) month
};
const currentMonthsSince1990 = () => {
let d = new Date();
return 12 * d.getYear() d.getMonth() 1;
}
const isExpiryValid = string => {
let now = currentMonthsSince1990()
let exp = monthsSince1900(string);
return exp > now 3
}
console.log(isExpiryValid('1121')); // 11/21 will expire soon
console.log(isExpiryValid('1221')); // 12/21 will expire soon
console.log(isExpiryValid('122')); // 1/22 will expire soon
console.log(isExpiryValid('222')); // 2/22 is good
console.log(isExpiryValid('322')); // 3/22 is good
<iframe name="sif4" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>