what is the fastest way to check for a valid DateTime? I need to take into account not just that the string cointains year, month, day, hour and minute, but also that the datetime is valid, eg: 2017-02-29 10:00 should be considered not valid because it is 29th in a non leap year.
I have an array of string elements (300k elements) in the format: YYYYMMDDHHmm
, and I need to check each line in the fastest way possible.
Using moment.js to check validity of each elements requires around 5s
in a regular for loop:
for (let i = 0; i < length; i++) {
let el = datetimes[i];
let d = moment.utc(el, "YYYYMMDDHHmm");
d.isValid();
}
Are there faster alternatives?
Rule out as much as you can before calling any kind of string matcher or regular expression.
moment is going to evaluate that expression EVERY time. (unless is has come creative caching going on)
You can check for falsy values first (undefined, null, 0, '', etc).
if (!el) {
// not valid
}
You can check the length after checking null and undefined (thanks Luca)
if (el.length !== 12) {
// not valid
}
You can also precompile a REGEX and use that.
// define this outside of your loop
let rx2 = /^(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})$/
function leapYear(year) {
return ((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0);
}
function checkValidDate(strDate) {
if (!strDate || strDate.length !== 12) throw new Error('invalid date')
let m = rx2.exec(strDate)
if (!m) throw new Error('invalid date')
let year = parseInt(m[1])
if (year < 2000 || year >= 2100) throw new Error('bad year')
let month = parseInt(m[2])
if (month > 11) throw new Error('bad month')
let day = parseInt(m[3])
// base 0 days and months
switch (month) {
case 0, 2, 4, 5, 6, 7, 9, 11:
if (day > 30) throw new Error('bad day')
break;
case 3, 5, 8, 10:
if (day > 29) throw new Error('bad day')
break;
case 1:
if (day > 28) throw new Error('bad day')
if (day === 28 && !isLeapYear(year)) throw new Error('bad day')
break;
}
let hour = parseInt(m[4])
if (hour > 23) throw new Error('bad hour')
let minute = parseInt([5])
if (hour > 59) throw new Error('bad minute')
}
try {
checkValidDate('asdf')
console.log('valid')
} catch (e) {
console.error(e)
}
try {
checkValidDate('200011241230')
console.log('valid')
} catch (e) {
console.error(e)
}
try {
checkValidDate('200001300000')
console.log('valid')
} catch (e) {
console.error(e)
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With