It doesn't have to do with substr -- it's operator precedence: . and + have equal precedence and left associativity. So "0" . localtime->mon() + 1 is the same as ("0" . localtime->mon()) + 1 -- it performs the concatenation operation first, resulting in "00", which is converted to a number, 0, for the addition, resulting in 1 (for the current month, January).
bash-2.05b$ perl -MTime::localtime -e 'print "0" . localtime->mon() +
+ 1, "\n"'
1
bash-2.05b$ perl -MTime::localtime -e 'print +("0" . localtime->mon())
+ + 1, "\n"'
1
bash-2.05b$ perl -MTime::localtime -e 'print "0" . (localtime->mon() +
+ 1), "\n"'
01