Windowsバッチ 時刻取得の罠

2021年12月16日

どうも、ささっきーです。
最近Windowsバッチを触っていて日時を取得する部分ではまったことについて、メモしておきます。

実行時間によるエラー

ざっくりいうと、実行日時を含めた名前を先頭にくっつけてリネームしたフォルダを作成するというバッチがありました。

例.
2018/10/1 午前12:00実行時
→作成フォルダ:201810011200

普通に実行していると特に問題なく動いてくれていたんですが、たまたま9:00台に実行したときにおかしな動作が起きました。

例.
2018/10/1 午前9:00実行時
→作成フォルダ:20181001 (名前がおかしいぞ!?)

プロンプト上には「コマンド構文の誤りがあります」と、何やら怪しいログが出ておりました。

時刻取得の方法

時刻取得については以下のような実装。

補足しますと、まず「%time%」で現在時刻を取得できます。
ただ、取得した形のままではフォルダ名としては使用できない文字が含まれるため、
整形してあげる必要があります。

そこで、上記実装のように必要部分を抜き出して連結しています。
実行結果は下記の通り。

※「~0,2」:0文字目から2文字分
※その他細かい整形についてはググっていただければいろいろ出てきます

%time%で取得できる時刻の仕様

今回の誤動作ですが、結論から言えば時刻取得部分の実装がよろしくなかった、ということでした。

「%time%」で取得した際、時刻によって※は先頭に空白が入っているんですね。
※0:00:00~9:59:59 1桁台の時刻
なので午前9:00に取得した結果は「 9:00:00.00」となります。

つまり、上述した方法で文字列を取り出していても午前9:00に時刻を取得した場合「 900」という文字列に整形されてしまいます。
空白が含まれることにより、引数の区切りとして扱われ思わぬ動作を起こす原因となります。

先頭0埋めで取得できたらよいのに・・・

「0」に置換しておこう

この不具合ですが、あらかじめ空白部分を「0」に置換することで対応しました。

↑このように記述することで空白を「0」で置換してくれます。
※「 900」→「0900」となる
置換対象が含まれていない場合はスルーしてくれるみたいなので、特に問題はなさそうです。

まとめ

実行時刻を取得して名前を付けるという処理はテンプレートレベルでよくある実装かとは思いますが、もしかすると問題がある実装がちらほらと存在しているかもしれませんね。

10:00~23:59の間にしか実行しないバッチであれば、とりあえずは問題ないですし。
ただ、手動でのリバッチが必要な時などに上記問題が見つかる、なんてこともあるかもしれないので、この辺の実装をするときは気を付けておきたいと思います。