バッチで日付と時刻を取得する

言語環境によらずに日付と時刻を取得するには?


近所の横浜スタジアムでは、横浜DeNAベイスターズ夏の一大イベント、YOKOHAMA STAR NIGHT 2015が開催されているみたいです。
特別なユニフォームを来場者全員に配布するというイベントなのですが、今年はなかなか人気があり、チケットを取るのが難しかったようです。

各球団、最近は、色々とファンサービスに力を入れているようですね。
同じユニフォーム配布系のイベントだと、ジャイアンツは橙魂、ホークスは鷹の祭典なんて名前みたいです。
ドラゴンズは昇竜という名前のようですが、来年からは、スターナイトに習って、ドラゴンナイトというのはどうでしょうか?
ドラゴンナイトのキャッチコピーも考えてみました!

Nagoya Dragon Night 〜今宵、俺たちは友達のように歌うだろう〜

何行もかけて、これが言いたかっただけですね!

さて、本題に入ります。


言語環境によらずに日付と時刻を取得する

ログを取るバッチを作成したときなど、日付と時刻をフォルダ名やファイル名に使用したい場合があると思います。
そんなときに、日付と時刻を取得する方法について説明します。
また、日本語環境と英語環境での違いによらず、取得できるようにしています。

全体は下記のようになっています。
これを拡張子.batとして保存して、ダブルクリックすると、日付と時間が"-"で区切られて表示されるはずです。

このバッチは、8〜47行目のNOWというサブルーチンの中で、YEAR, MONTH, DAY, HOUR, MINUTE, SECOND, MILLISECONDという変数に現在の日付と時刻が格納するようになっています。

以下にサブルーチンを説明します。

PCの言語環境を判断する

サブルーチンの11〜20行目では、日付のフォーマットから、PCの言語環境を判断します。
私の知っている限り、Windowsの日付のフォーマットは下表の4つがあります。
他にもあるかもしれませんが、私が仕事の中で当たるPCはこのぐらいしかないので、この4つだけ判別できればよしとします。
それぞれ、"/"の位置が異なるので、判断は"/"の位置で行うことにしています。

日付のフォーマット
言語 フォーマット "/"の位置(前から数えた場合) "/"の位置(後ろから数えた場合)
日本語1 2015/08/20 4, 7 3, 6
日本語2 木 2015/08/20 6, 9 3, 6
英語1 Thu 08/20/2015 6, 9 5, 8
英語2 08/20/2015 Thu 2, 5 9, 12

後ろから3文字目が"/"なら、日本語(YYYY/MM/DDの並び)と判断します。
さらに、後ろから10文字を切り出し、YYYY/MM/DDの部分だけを抽出します。
後ろから5文字目が"/"なら、英語(MM/DD/YYYYの並び)として、前から5文字目から最後までを切り出し、MM/DD/YYYYの部分だけを抽出します。
それ以外なら、英語(MM/DD/YYYYの並び)として、最後の4文字を除き、MM/DD/YYYYの部分だけを抽出します。

日付を年、月、日に分けて変数に格納する

ここまでで、YYYY/MM/DDまたはMM/DD/YYYYの文字列が抽出できていることになっています。
22〜30行目で、日本語/英語で場合分けして、抽出した文字列の一部をスライスして、変数YEAR, MONTH, DAYに格納します。

一応、文字列のスライスの書式を下記の表にまとめます。

バッチの文字列のスライス
書式 意味
%str:~m% strという文字列の、m文字目以降
%str:~m,n% strという文字列の、m文字目以降のn文字分
%str:~m,-n% strという文字列の、m文字目以降の、後ろからn文字分を除去したもの
%str:~-m% strという文字列の、後ろからm文字目以降
%str:~-m,n% strという文字列の、後ろからm文字目以降のn文字分
%str:~-m,-n% strという文字列の、後ろからm文字目以降の、後ろからn文字分を除去したもの

時刻を時、分、秒、ミリ秒に分けて変数に格納する

32〜36行目では、時刻を変数に格納します。
ポイントは、0~9時までは、" 9:00:00.00"のようにスペースが入るので、スペースを0で置換している点です。

置換は以下のように行います。

バッチの文字列の置換
書式 意味
%str:x=y strという文字列の、文字xを文字yに置換

ローカル変数の使用と、ローカル変数の外部への渡し方

サブルーチン内で、意図せず同じ名前の変数を更新してしまわないように、ローカル変数を使用しています。
バッチでは、setlocal〜endlocalの間の変数は全てローカル変数扱いとなり、外部の変数に影響を与えません。

しかし、最後に、サブルーチン内でローカル変数に格納した処理結果を、外部に渡す必要があります。
その場合は、下記のように記述します。
hogeの内容はsetlocal〜endlocalの外部では参照できませんが、endlocalに"&&"で続けて、外部から見ることができる変数fugaへの代入を行うことで、外部にhogeの内容を渡すことができます。

setlocal
set hoge=100
endlocal && set fuga=%hoge%

38〜45行目で、外部にYEAR, MONTH, DAY, HOUR, MINUTE, SECOND, MILLISECONDの値を渡しています。


Comments