29 августа 2010

Календарь+parseInt == нетривиально

Не так давно довелось использовать код javascript dropdown календаря от Martijn Korse. Все было хорошо, пока не случилась одна вещь: календарь перестал отдавать правильную дату. Точнее, день выдавал правильный, а вот месяц нет. Но все оказалось еще сложнее...
В нескольких местах в коде используется функция parseInt(). Все было хорошо, пока в функцию не стала передаваться строка с ведущим нулем, да еще и с числом больше 8 (уже догадались, да?). Казалось бы, parseInt("08")=8, а parseInt("09")=9, но это не так. parseInt("09")=0! O_o
Почему?
Наверное, мало кто задумывается об этом... Документация по функции говорит, что функция ведет преобразование до первого невалидного символа, то есть как только встречается невалидный символ, преобразование прекращается и функция возвращает, что она до этого момента напреобразовывала... И второй момент: система счисления определяется автоматически по виду строки. То есть 0x123 автоматически распознается как шестнадцатиричное число, а число с ведущим нулем - как восьмеричное.
Вот теперь становится понятно, почему parseInt("05")=5, а parseInt("09")=0. Пятерка - валидный восьмеричный символ, а девятка нет. Поэтому parseInt("09") возвращает результат до девятки, то есть НОЛЬ. Если бы число совсем не удалось бы преобразовать - результатом был бы NaN.
Решение: явно указывать основание системы счисления вторым параметром функции. Например, parseInt("09", 10) вернет 9.