views:

55

answers:

4

I'm parsing a string to check if it's a date, and by chance we now discovered that my method doesn't work for dates in august or september. This is what I do (the input isn't really hard-coded, obviously, but for brevity...):

var str = '2010-08-26 14:53';
var data = str.split(' ');  // ['2010-08-26', '14:53']
var date = data[0].split('-'); // ['2010', '08', '26]
var time = data[1].split(':'); // ['14', '53']

var yyyy = parseInt(date[0]); // 2010

// THIS IS WHERE STRANGE THINGS HAPPEN:
var MM = parseInt(date[1]); // 0 - not 08 or 8, as expected!
console.log(date[1]); // prints "08" (with quotes)
console.log(date[1].toString()); // prints 08 (no quotes)
console.log(parseInt(date[1].toString())); // prints 0 (!)

This problem arises for august and september, and for the 8th and 9th every month - that is, when either "08" or "09" is being parsed to integer, 0 is returned instead of 8 or 9. The code works for both lower (e.g. "07") and higher (e.g. "10") integers (at least within expected date ranges...)

What am I doing wrong?

+4  A: 

Use

parseInt(date[1], 10)

to make sure the string is interpreted as base 10 (decimal).

Otherwise, it is interpreted as base 8 (octal) if it starts with "0", or as base 16 (hexadecimal) if it starts with "0x".

In fact, you should always include the base argument to avoid these kinds of bugs.

Tomalak
Fun fact: The second argument ("radix") can be any integer from 2 to 36, allowing for many esoteric number systems that use ASCII letters and numbers for presentation.
Tomalak
+1 for the last sentence. A step I am usually too lazy to do >_<... it'll save you from so many headaches
ItzWarty
+1  A: 

That's because numbers that start with 0 are treated as octal numbers and "08" is not an octal so 0 is returned.

Read this: http://mir.aculo.us/2010/05/12/adventures-in-javascript-number-parsing/

mck89
A: 

It sounds like your date is being parsed as hex - the leading zero is doing this.

Because the hex and decimal representations are the same for 0-7 it 'works', but 8 and 9 get incorrectly converted.

Use

parseInt(date[1], 10)

To specify the base explicitly.

Visage
A: 

The parseInt() function has the second optional radix parameter. If the radix parameter is omitted, JavaScript assumes the following:

  • If the string begins with "0x", the radix is 16 (hexadecimal)
  • If the string begins with "0", the radix is 8 (octal). This feature is deprecated
  • If the string begins with any other value, the radix is 10 (decimal)

So in your case it assumes the octal numbers. Change to var MM = parseInt(date[1], 10); and it will work

ZloiAdun