Rob discovers his Javascript inadequacies, chapter 442

It will probably come as no surprise to anyone who's given this blog a cursory glance, but today I once again tripped over yet another hole in my JS knowledge. At work I maintain several web applications for booking meeting rooms, because one of the main initial design requirements was 'make it work like the desktop version' and the developers who've worked on it in the past (myself included), mostly working under extreme time pressure, had, at best, a patchy understanding of Javascript, there's a lot of quite hairy code in the UI that just barely works. Making apparently small incremental improvements can lead to days long odysseys through the several thousand lines of code as you track down all the bugs you created by 'fixing' something. In particular, there is a significant amount of code devoted plucking apart, comparing and rebuilding date strings, including several exciting functions where dates are calculated by working out how many milliseconds there are in a day and working forward from there.

This tends to leave us with a swathe of bug reports every time something slightly out of the ordinary crops up, which it's my job to fix. Recently a client reported a problem where they were unable to book any rooms in 2008. I isolated the problem to a single function, run in the onload event, which takes a date in dd/mm/yy format delivered from a Java applet, transforms it into the standard format for the server side app and then sticks it in a hidden field. Everything in '07' worked just fine, but anything in '08' ended up producing a date in 2000. The culprit was the parseInt function, and the thing I didn't know was that numbers with a leading zero are interpreted as octal, and, of course, '08' is not a valid octal number so the parseInt returned zero (and then had 2000 added to it, hence the final date). A change to parseInt(strYear, 10) fixed the problem immediately.

As I scrolled through the code to look for other issues this may be causing I came across evidence that others (possibly even myself, it's hard to remember) had covered this ground before - a function called removeLeadingZeroes featured fairly commonly inside parseInt parameters.

Every so often it's good to remind yourself how much you don't know...