Date Validation That Went Wrong

Date validation that went wrong

Validating dates in JavaScript can be tricky at times and as of writing there is no a standard way for developers to properly validate a date. There are couple of methods people use to validate a date but from what I used to use is to call .toJSON() method on a Date instance to check if it returns null. This has been pretty useful and straightforward for a simple date validation until I got hit by a weird behavior when Apple Safari 9 is involved.

Here's what happened to me:

const randomDate = new Date(''); // returns Date instance but it is an Invalid Date

/**
 * Invalid Error on Safari 9 while other browsers return `null` (even IE11)!
 * 😲 That's weird.
 */
randomDate.toJSON();

Lesson learnt from this is that unlike other browsers, Safari 9 does not handle invalid dates correctly when trying to JSON.stringify an invalid date. I have to resort to another approach to validate a date to ensure it works on all modern and old browsers that I have to support.

Long story short, the old-school way of validating a date is to check if a Date instance returns a UNIX timestamp which is of type number in JavaScript otherwise NaN for any invalid date. So, this is how the code looks like, at least for my use case:

function isValidDate(date: unknown): boolean {
  /**
   * Definition of invalid date for my use case:
   * 1. Nullish date
   * 2. Not a `Date` instance
   * 3. A Date instance that returns NaN instead of UNIX timestamp
   */
  const isInvalid = (
    date == null ||
    !(date instanceof Date) ||
    isNaN(date.getTime())
  );

  return !isInvalid;
}

// False:
isValidDate(null);
isValidDate(void 0);
isValidDate([]);
isValidDate({});
isValidDate(new Date(void 0));
isValidDate(new Date(null));

// True:
isValidDate(new Date('2020-02-02'));

The code above is not robust enough to handle other cases like validating a UNIX timestamp but this is more than enough for my use case as long as the input is a Date instance and not an Invalid Date. This is not aiming to be a one-size-fits-all solution for all use cases out there but knowing what you will need is somewhat important in a given context.

Wrap up

Even though .toJSON() works perfectly fine on modern browsers, there is still some gotcha when you need to support old browser like Safari 9 which in this case does not handle invalid date that well. This is my attempt to rectify the mistake I had made - to check if the date conversion to timestamp returns NaN.

This seems like an extra step to copy this piece of code if that works for you just fine. You're in luck! I've been working on a new open source project that provides a collection of extensions to make JavaScript a better programming language which I find inspiration in my learning of new programming languages (Rust, Dart, etc). Checkout jsmodern and you can use it in your project today.

That is it. Have a wonderful day ahead and I'll catch you on the flip side. Peace! ✌️