Date validation that went wrong
Table of contents
Date validation in JavaScript
Validating dates in JavaScript can be tricky at times, and as of writing, there is no standard way for developers to properly validate a date. There are a couple of methods people use to validate a date, but the one I used to use is to call the Date.prototype.toJSON() method on a Date instance to check if it returns null. This has been pretty useful and straightforward for simple date validation until I encountered a weird behavior when Safari 9 was 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 learned from this is that, unlike other browsers, Safari 9 does not handle invalid dates correctly when trying to JSON.stringify() an invalid date. I had 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 what the code looks like 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 it 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 need is somewhat important in a given context.
Wrap-up
Although Date.prototype.toJSON() works perfectly fine on modern browsers, there are still some gotchas when you need to support old browsers like Safari 9, which, in this case, does not handle invalid dates well. This is my attempt to rectify the mistake I had made: to check if the date conversion to a timestamp returns NaN.
This may seem like an extra step to copy this piece of code if it works just fine for you. 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. I find inspiration in my learning of new programming languages like Rust, Dart, etc. Check out jsmodern, and you can use it in your project today.
That's it. Have a wonderful day ahead, and I'll catch you on the flip side. Peace! ✌️