JavaScript and its love for zeroes
Answer quick. Do you know what date is being created here?
var year = '2009', month = '09', day = '01'; var date = new Date( parseInt(year), parseInt(month), parseInt(day) );
At first glance, it wouldn't surprising that someone guesseed September 1st 2009. However, I'd not be writing this post if that was the correct answer, right?
There's an interesting and tricky thing with the JavaScript parseInt
function: it
can parse strings with a numeric value in the decimal radix, but also in other radices. See the
following examples.
//passing the radix explicitly parseInt('1011', 10); // ==> 1011 parseInt('1011', 2); // ==> 11 parseInt('1011', 8); // ==> 521 parseInt('1011', 16); // ==> 4113
Maybe you thought that if you didn't pass the radix, then it would default to 10 because it's the obvious behavior. Well, no. In JavaScript the default behavior is to try to identify one of the literal formats and interpret that. So here's that in action:
//leaving JavaScript on its own parseInt('1011'); // ==> 1011 (decimal literal) parseInt('0x12'); // ==> 18 (hexadecimal literal) parseInt('0511'); // ==> 329 (octal literal) parseInt('0182'); // ==> 1 (whaaaa?!?!)
If you are familiar with the literal notation for integer numbers in JavaScript,
and after I explained the default behavior of parseInt
, then
you probaly understood the results shown above. Well, maybe the last one deserves
some comments.
When JavaScript is parsing the string, if it finds a digit (number or alpha) that is invalid
in the chosen radix, it stops right there and parses only the portion of the string that
comes before that digit. So, since we started '0182'
with a leading zero, the
octal radix is assumed. Then, because 8 is not a valid octal digit, only '01'
will be parsed, which becomes 1.
parseInt
call. If you're extra paranoid, then always pass the radix.
Back to our original question
Armed with the clarification made above, we can expand our example like this:
//given: var year = '2009', month = '09', day = '01'; // then the following statement: var date = new Date( parseInt(year), parseInt(month), parseInt(day) ); //...is equivalent to: var date = new Date( 2009, 0, // ===> oopsie 1 );
Hmmm, a zero in the month parameter. Will we have an error here? No, here comes the second potential surprise of this post.
new Date(year, month, day)
, the month
parameter, and only the month parameter is zero-based (0 to 11).
So, in case the tips and the picture in this text were not enough to help you guessing the date being created, here goes another completely gratuitous one with the answer.