Daily WTF

What The Fuck Cat

Today, I found the strangiest bug of the month; I was parsing some date parts with JavaScript to properly set default month of a YUI Calendar instance.

var month = parseInt(Drupal.settings.mymodule.date.month) - 1;
myCalendar.setMonth(month);

Why -1? Because month count starts with 0 in YUI Calendar, January is 0, december is 11; everything is fine until here.

Why the FUCK does my calendar always get to december?

You have to know this, today is 18/08/2009. So, my month is "08" in my global Drupal.settings.mymodule.date.month variable. This is useful for us to reconstruct dates with the leading 0s included. This allows us to make SQL dates without testing the leading 0's presence.

So, WHY DECEMBER is my default month displayed?

Let's look at the parseInt() function specification. When we read the small lines, we can read this:

The parseInt() function parses a string and returns an integer.

The radix parameter is used to specify which numeral system to be used, for example, a radix of 16 (hexadecimal) indicates that the number in the string should be parsed from a hexadecimal number to a decimal number.

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)

If a did a good reading, my "08" string becomes, with the help of parseInt(): "8 in octal", which does not means anything, because 8 does not even exists in octal.

What really happens here is

  • "8" becomes "8 in octal" 
  • "8 in octal" does not exists, which gives us 8 modulo 8 (I suppose), which is 0 
  • which get to 0 - 1 thanks to YUI counting monthes from 0, which is -1 
  • Then, YUI Calendar says -1 modulo 12 which gives us 11 
  • TADA! We are in December !

How to fix this?

Just be smart, RTFM, and write this:

var month = parseInt(Drupal.settings.mymodule.date.month, 10) - 1;
myCalendar.setMonth(month);

May the Double WTF be with you!

#1 – More fun

And do you know what's really fun with this bug?

We did this code something like arround january, we never saw it until august. The fact is that all numbers from 1 (january) to 7 (july) are the same in decimal or octal.

So in august, all is breaking!

What's more fun is I comited a fork of this code as an official Drupal contrib module; module usage statistics says that arround 30 people are using it.

#2 – Tripple WTF ?

maybe this should work better ?
var month = parseInt(Drupal.settings.mymodule.date.month, 10) - 1;
myCalendar.setMonth(month);

#3 – Triple oooups

Heh typo error on post, I fixed it!

#4 – To know in php

There is also some things to know in php with radix :
<?php
function disp($v) { echo 1 * $v . "\n"; }
disp(12); // echoes 12
disp('12'); // echoes 12
disp(012); // echoes 10
disp('012'); // echoes 12
disp(0x12); // echoes 18
disp('0x12'); // echoes 18
?>

#5 – I always use casts, no

I always use casts, no surprises, faster and more secure than any other conversion function.

Post new comment

The content of this field is kept private and will not be shown publicly.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Allowed HTML tags: <a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd>
  • Lines and paragraphs break automatically.
  • Use [fn]...[/fn] (or <fn>...</fn>) to insert automatically numbered footnotes.
5
a
F
e
k
g
Enter the code without spaces and pay attention to upper/lower case.