SET /A で計算する時は注意!

突然ですが、下記バッチはバグを含んでいます。。
どこだか分かります?

:: 実行年月の1ヶ月前をYYYYMM形式で出力

::デバッグ用
set DT1=201001
::set DT1=%date:/=%

set YYYY=%DT1:~0,4%
set MM=%DT1:~4,2%

::ゼロ埋めするかどうか
set FLG_ZERO=0
if "%MM%"=="01" goto NOT_ZERO
if "%MM%"=="12" goto NOT_ZERO
if "%MM%"=="11" goto NOT_ZERO
set FLG_ZERO=1

:NOT_ZERO

::前年月を算出
if "%MM%"=="01" (
	set /a YYYY-=1
	set MM=12
) else (
	set /a MM-=1
)

::ゼロ埋め
set YYYYMM=
if "%FLG_ZERO%"=="1" (
	set YYYYMM=%YYYY%0%MM%
) else (
	set YYYYMM=%YYYY%%MM%
)

echo %YYYYMM%

pause


まあ、どうってことないんです。実行した年月の1ヶ月前を表示するだけのバッチです。
例えば今月実行したら201012と出るみたいな。
サーバのログを収集するバッチの中で、一部手動の箇所があったんで、
ちょっと自動化しようと思った中の一品です。


でも、はまりました。。
DT1に201009とか入れてみてください。
結果が、20100-1となってしまいます(>o<)
バグの原因は、

else (
	set /a MM-=1
)

こいつなんですけど、どうも分からない。。
というか、MMに09と08が入ると-1になる事がわかった。
でもなんでが分からず、周りを巻き込み思考タイム。


どうです?分かります??
私は指摘されるまでじぇんじぇん分からなかったです(恥)


ある先輩が、教えてくれました。『ヘルプをみろ』と。
で、ヘルプ*1を追っていくとこんな記述を発見。

数値は 10 進数ですが、プレフィックスとして 0x
を付けると 16 進数、0 を付けると 8 進数になります。従って、0x12 は 18、
あるいは 022 と同じです。
8 進表記を使う場合は、注意してください。08 や
09 は、8 と 9 が有効な 8 進数ではないため、
有効な数値ではありません。


ohh!マジっすか。orz

*1:set /?で