Javascript date jank
So I'd thought I'd share a lovely piece of Javascript jank one of the other devs at work encountered.
Also, before we begin: this isn't implementation advice, don't do this. It is bad. It's just some fun stuff we found. (with that out of the way...)
So what they were trying to do was get a date object for a specific amount of time before/after another date object. This is what they tried:
let myDate = new Date() let myNewDate = new Date(myDate - (numMinutes * 60 * 1000))
Hopefully it's pretty clear what it's trying to do. It's trying to make a Date numMinutes before myDate. And this does what you would expect: so far so good!
So next they were trying to get a Date object for numMinutes later than myDate. Given what we just saw, easy right?
let myDate = new Date() let myNewDate = new Date(myDate + (numMinutes * 60 * 1000))
And just quickly typing this into the console as sanity check (on Firefox):
Invalid Date
huh? Wha?
Yeah, it took me a sec too.
Basically, what's going on here is the Javascript interpreter is trying be helpful. When the interpreter is running the version with the minus, it sees you are trying to subtract a number from a Date object. This doesn't make any sense, so it ever helpfully steps in and just tries to make it work. And it does. It decides it needs to coerce the type of at least one of the variables. It figures out if it converts the date into a Unix timestamp (which is just a number) the subtraction works! The resulting number is given to the Date constructor and it interprets the number as a Unix timestamp and spits out the correct answer.
Yipeeeeeee
But why does the version with the plus not work?
It's the same principle. The interpreter sees that you are trying to add a Date and a number, which doesn't make any sense. So it tries to be helpful and make the types work. It just so happens the interpreter figures out if it casts the Date to a string and the number to a string they can be plussed together. This makes it a string concatenation. So a valid date string with a random number on the end get passed to the Date constructor, and hey presto, Invalid Date!













