parseInt の罠
2006年9月2日 コンピュータ7月、JScript での話。
元々は文字列を日付に直そうとしていた。
しかし、
「YYYY-MM-DD hh:mm:ss.nnn」
って形の日付(例えば「2006-07-30 09:12:34.567」) を
JScript の Date Object の Constructor の
new Date(str)
の書式は受け付けてくれなかった。
で、仕方が無いので構文解析してばらばらにし、
JScript の Date Object の Constructor の別の書式
new Date(year,month,day,hour,minute,second,millisecond)
を使うことにした。ここで注意しなければならないのは
month の値は 「1〜12」ではなく、「0〜11」である。
・・・っというわけでこんなコードを書いてしまった。
(注:危険なコード)
new Date(strYear,parseInt(strMonth)-1,strDay,
strHour,strMinute,strSecond,srtMillisecond)
テストしてもきちんと正しく動作した。
ただし、それは 7月の話。
8月になって、データの日付を見ていると、
昨年の 12月になってる。
テストで使ったスクリプトを動かしても
昨年の12月になる。
なんでだ〜〜〜〜
調べていくと、
parseInt("08")
が 「0」を返している。
うぅ・・・。0 が付いていると
解釈できなくなるのかなぁ・・・。
マニュアルで parseInt を見てみる。
う〜ん・・・ 0 が付いていると
0 になるなんて書いてないなぁ・・・。
お手洗いに立って用を足しながら考える。
・・・あっ。(エウレカ!)
マニュアルを見返すと
「0 で始まるときは 8進数で解釈される」
とある。これだぁ〜〜〜〜。
つまり、0 から始まるので 8進数と解釈しようとし、
8進数では 8 は数字で無いので 0 までで解釈をして
0 となっていた。そして Date のコンストラクタの月のところに
範囲外の -1 が与えられて昨年の 12月だった。
7月の場合は 07 が与えられて8進数で解釈しても
10進数の 7 になっていたので問題が発覚しなかったのだった。
(つまり、8月、9月限定で障害が出る。)
そういうわけで明示的に進数を指定して
new Date(strYear,parseInt(strMonth,10)-1,strDay,
strHour,strMinute,strSecond,srtMillisecond)
としないといけなかった。
うぅ・・・・・。
元々は文字列を日付に直そうとしていた。
しかし、
「YYYY-MM-DD hh:mm:ss.nnn」
って形の日付(例えば「2006-07-30 09:12:34.567」) を
JScript の Date Object の Constructor の
new Date(str)
の書式は受け付けてくれなかった。
で、仕方が無いので構文解析してばらばらにし、
JScript の Date Object の Constructor の別の書式
new Date(year,month,day,hour,minute,second,millisecond)
を使うことにした。ここで注意しなければならないのは
month の値は 「1〜12」ではなく、「0〜11」である。
・・・っというわけでこんなコードを書いてしまった。
(注:危険なコード)
new Date(strYear,parseInt(strMonth)-1,strDay,
strHour,strMinute,strSecond,srtMillisecond)
テストしてもきちんと正しく動作した。
ただし、それは 7月の話。
8月になって、データの日付を見ていると、
昨年の 12月になってる。
テストで使ったスクリプトを動かしても
昨年の12月になる。
なんでだ〜〜〜〜
調べていくと、
parseInt("08")
が 「0」を返している。
うぅ・・・。0 が付いていると
解釈できなくなるのかなぁ・・・。
マニュアルで parseInt を見てみる。
う〜ん・・・ 0 が付いていると
0 になるなんて書いてないなぁ・・・。
お手洗いに立って用を足しながら考える。
・・・あっ。(エウレカ!)
マニュアルを見返すと
「0 で始まるときは 8進数で解釈される」
とある。これだぁ〜〜〜〜。
つまり、0 から始まるので 8進数と解釈しようとし、
8進数では 8 は数字で無いので 0 までで解釈をして
0 となっていた。そして Date のコンストラクタの月のところに
範囲外の -1 が与えられて昨年の 12月だった。
7月の場合は 07 が与えられて8進数で解釈しても
10進数の 7 になっていたので問題が発覚しなかったのだった。
(つまり、8月、9月限定で障害が出る。)
そういうわけで明示的に進数を指定して
new Date(strYear,parseInt(strMonth,10)-1,strDay,
strHour,strMinute,strSecond,srtMillisecond)
としないといけなかった。
うぅ・・・・・。
コメント