I have the following strings:
a='Check 134', a='2020-01-15T10:47:54Z', a='1234', a= some object
I want to check, whether the string is a date or not.
I tried:
new Date(a) instanceof Date &&
!isNaN(new Date(a).getTime())
, but it returns true for a='Check 123', whenever it has numbers.
What could be a better solution?
Note: I do not want to use momentjs, because of project restrictions
It is possible to check whether the string contains year
, month
, day
. In addition, we can add some conditions to have stricter rules to define whether string is Date
:
const isDate = str => {
let [y,M,d,h,m,s] = str.split(/[- : T Z]/);
return (y && M <= 12 && d <= 31) ? true : false;
}
An example:
const isDate = str => {
let [y,M,d,h,m,s] = str.split(/[- : T Z]/);
return (y && M <= 12 && d <= 31) ? true : false;
}
console.log('Check 134', isDate('Check 134'))
console.log('2020-01-15T10:47:54Z', isDate('2020-01-15T10:47:54Z'))
console.log('1234', isDate('1234'))
console.log('13-13-13', isDate('13-13-13'))
Actually, the question should be: how to determine if a given string can be converted to a real Date
object?
Now, more things than you like may be converted to a Date
(e.g., try new Date("")
or new Date(0)
). So you may want to use your own restrictions as to what you want to convert. Here's a method that restricts input to either a real Date
object or a String
:
const canConvertToDate = trial =>
[String, Date].includes(trial.constructor) &&
!isNaN(new Date(trial));
console.log(`canConvertToDate(\`\`): ${canConvertToDate(``)}`);
console.log(`canConvertToDate(\`no dice\`): ${canConvertToDate(`no dice`)}`);
console.log(`canConvertToDate(new Date): ${canConvertToDate(new Date)}`);
console.log(`canConvertToDate(\`2020-03-03 00:00:00\`): ${
canConvertToDate(`2020-03-03 00:00:00`)}`);
console.log(`canConvertToDate(0): ${canConvertToDate(0)}`);
console.log(`canConvertToDate(\`Wed, 11 Mar 2020 09:27:50 GMT\`): ${
canConvertToDate(`Wed, 11 Mar 2020 09:27:50 GMT`)}`);
console.log(`canConvertToDate(new Date().toUTCString()): ${
canConvertToDate(new Date().toUTCString())}`);
console.log(`canConvertToDate(134): ${canConvertToDate(134)}`);
// Please note the browser difference (Chrome / Firefox)
console.log(`canConvertToDate(\`134\`): ${canConvertToDate(`134`)}`);
.as-console-wrapper { top: 0; max-height: 100% !important; }
The previous snippet will not always give you the desired result (see comments).
Alternatively you can also write a parser of some kind to determine if the given string can be converted to Date
, to be more (but not 100%) certain that a string is convertable to Date
. Something like:
console.log(`tryParseDate(\`\`): ${tryParseDate(``).date}`);
console.log(`tryParseDate(new Date): ${tryParseDate(new Date).date}`);
console.log(`tryParseDate(\`Wed, 11 Mar 2020 09:27:50 GMT\`): ${
tryParseDate(`Wed, 11 Mar 2020 09:27:50 GMT`).date}`);
console.log(`tryParseDate(\`check 134\`): ${tryParseDate(`check 134`).date}`);
console.log(`tryParseDate(\`3-3-2005\`, \`ddmmyyyy\`): ${
tryParseDate(`03-03-2005`, `ddmmyyyy`).date}`);
console.log(`tryParseDate(\`12-22-1998 22:22:10.345\`, \`mmddyyyy\`): ${
tryParseDate(`12-22-1998 22:22:10.345`, `mmddyyyy`).date}`);
console.log(`tryParseDate(\`29-02-2019 22:22:10.345\`, \`ddmmyyyy\`): ${
tryParseDate(`29-02-2019 22:22:10.345`, `ddmmyyyy`).date}`);
function tryParseDate(someString, format = `yyyymmdd`) {
const invalid = {cando: false, date: new Date(`invalid`)};
if (someString.constructor !== String) { return { ...invalid, date: `Invalid Date: input not a string` }; }
const between = (val, lower, upper) => val >= lower && val <= upper;
const d = someString.split(/[/\- T:.]/g);
if (d.length < 3) { return {...invalid, date: `Invalid Date: can't split to anything useful`}; }
const formats = format.match(/(yyyy)|(mm)|(dd)/gi);
const values = {
year: +d[formats.findIndex(v => v === `yyyy`)],
month: +d[formats.findIndex(v => v === `mm`)],
date: +d[formats.findIndex(v => v === `dd`)] };
const cando = !isNaN(values.year) && values.year > 0 &&
!isNaN(values.month) && between(values.month, 1, 12)
!isNaN(values.date) && between(values.date, 1, 31);
if (!cando) {
return {...invalid, date: `Invalid Date: the given value is not valid`};
}
const date2Parse = `${d[formats.findIndex(v => v=== `yyyy`)]}/${
d[formats.findIndex(v => v=== `mm`)]}/${
d[formats.findIndex(v => v=== `dd`)]} ${
d.slice(3).map((v, i) => !i ? v : i > 2 ? `.${v}` : `:${v}`).join(``)}`;
const parsed = new Date(date2Parse);
const checkLeap = parsed.getMonth() + 1 === values.month;
const error = `Impossible Date: ${
!checkLeap ? `${values.year} not a leap year` : `parsing failed`}`;
return isNaN(parsed) || !checkLeap
? {...invalid, date: error}
: {cando: true, date: parsed};
}
.as-console-wrapper { top: 0; max-height: 100% !important; }
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