1

I try to troubleshot my code and found a strange Date issue for js, I can't understand. On the developer tools of chrome, watch the value of this expression:

new Date(new Date() + (-1)  * 60 * 1000).getTime()

You will got value 'NaN'.

And if watch this:

new Date(new Date() + (-1)  * 60 * 100).getTime()

You will got value '1479095577000'.

Why?

5
  • 2
    You probably want to use Date.now() instead of new Date() in there. new Date().toString() returns a string ,then when you do + (-1) it concatenates instead of adding. So it returns something like "Fri Nov 11 2016 00:02:59 GMT-0800 (Pacific Standard Time)-60000"
    – mash
    Commented Nov 11, 2016 at 8:03
  • @mash but then why does the second code work?
    – KWeiss
    Commented Nov 11, 2016 at 8:04
  • @KWeiss honestly no clue, for some reason "Fri Nov 11 2016 00:05:05 GMT-0800 (Pacific Standard Time)-1000" is a valid date but "Fri Nov 11 2016 00:05:05 GMT-0800 (Pacific Standard Time)-10000" is not. Not really sure what the numbers after the - are being parsed as.
    – mash
    Commented Nov 11, 2016 at 8:07
  • Looks like it might be parsing the digits as the timezone delta from GMT, even though that's already in there. It seems to be ignoring the GMT-800 part, and just using the -xxxx part at the end that has been concatenated. There's only 4 digits assigned for the timezone delta, perhaps that's why it works up to -9999, but -10000 gives Invalid Date.
    – mash
    Commented Nov 11, 2016 at 8:12
  • As a side note: Do not try to do math on date objects as that mostly does not work the way you would expect it. Instead use the getter/setter methods of the date object or a better date framework like moment.js
    – str
    Commented Nov 11, 2016 at 8:15

3 Answers 3

2
  • new Date() + (-1) - the date get converted to string, then "-1" is concatenated to it, which is a valid date, because you're subtracting some time zone offset
  • new Date() + (-1) * 60 * 100 = new Date() + (-1 * 60 * 100) = new Date() + (-6000) - which is also a valid date minus some time zone shifting
  • but then a date minus 60000 is not a valid date, due to time zones having only 4 digits top
1
  • 1
    Awesome answer. I try to found the boundary value. new Date('Fri Nov 11 2016 16:11:01 GMT+0800 (China Standard Time)-9999'); It's OK. new Date('Fri Nov 11 2016 16:11:01 GMT+0800 (China Standard Time)-10000'); But not the above, it could prove Arhak's conclusion. And also I do some other trying, got the following rules. 1. If the end of number is one-digit or two-digit, it means hour. 2. If the end of number is three-digit or four-digital, the last 2 figures mean minute, the first 1 or 2 figures mean hour.
    – Eason
    Commented Nov 11, 2016 at 8:28
1

The Date object doesn't overload +, so new Date() + n simply concatenates both operands as strings.

Eg:

new Date() + (-1) * 60 * 1000

is equivalent to

String(new Date()) + String((-1) * 60 * 100)

and yields (depending on locale)

Fri Nov 11 2016 09:05:43 GMT+0100-6000

The second example yields a value because the "-6000" looks like a timezone modifier that subtracts sixty hours, even though there is already one. This is a parsing quirk of Chrome - Firefox will reject it, but Chrome will accept the "-6000" and yield a date sixty hours in the future.

This only works if the appended string is exactly four digits (the first two digits for the hours, two for the minutes), and has either a + or a - in front of it. That's why it works if you add "-6000", but not "-60000". It wouldn't work with positive numbers either, unless you added the "+" character manually.

I suspect that what you actually want is

Date.now() - 60 * 1000
2
  • Whether either expression returns a valid Date is entirely implementation dependent. Neither expression returns a valid date in Safari.
    – RobG
    Commented Nov 11, 2016 at 20:56
  • Yeah, since the string doesn't represent a valid date, there is no well-defined browser behavior. I've checked with a few, and it seems that Chrome is alone in accepting the syntax. Commented Nov 11, 2016 at 22:24
0

As others have said, the issue is that the first + causes string concatenation rather than addition. You can fix that using Date.now() or:

// Use unary +
console.log(new Date(+new Date() + (-1)  * 60 * 1000).getTime());

// Replacing `+` with `-`
console.log(new Date(new Date() - 1 * 60 * 1000).getTime());

The above may return slightly different results (±2ms or so) due to the performance of the SO console.

Note that whether new Date(new Date() + (-1) * 60 * 1000).getTime()) returns a valid date or not is entirely implementation dependent. Safari returns an invalid date for both expressions in the OP.

Not the answer you're looking for? Browse other questions tagged or ask your own question.