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