treedown’s Report

システム管理者に巻き起こる様々な事象を読者の貴方へ報告するブログです。会社でも家庭でも"システム"に携わるすべての方の共感を目指しています。

※https化しました。その影響でしばらくリンク切れなどがあるかもしれませんが徐々に修正していきます。 リンク切れなどのお気づきの点がございましたらコメントなどでご指摘いただけますと助かります。

バッチファイルで日付を比較して条件分岐

バッチファイルの判定条件に日付情報を使って処理をしたいことがあったので、検証してみた結果をご報告です。
バッチファイルで日付を変数に入れるとき、ちょっと気にした方がいい情報。

概要

毎日実行するバッチ処理の中に、ある特定の日付を検出して別処理を加える、というバッチ処理が必要になりました。
ただ、テストでやってみた結果、日付を数値として比較する条件分岐は、ちょっと工夫が必要だという結論に達しました。

その上手くいかなかったのを踏まえて、日付情報を数値としてを変数に入れて、比較処理はどう変化するかを記録しておきます。

最初にやったこと

最初にやっていたのは、

set daymmdd=%date:~5,2%%date:~8,2%

変数%daymmdd%に環境変数%date%の桁指定で日付の数字を入れたあと、

if %daymmdd% EQU %testnum%

で比較して条件分岐しようとしました。(EQUは「=」と同じ比較式)

すると、同じ数字を合致しないという結果に判定されてしまい、思ったような判定が出来ないという動作になってしまいました。(動く場合もある。)

これはちょっと不安があるということで、色々と判定を試してみることにしました。

検証したサンプルバッチファイル

以下のバッチファイルを作成して検証してみることにしました。もうちょっと色々やっていたのですが、結論としてこのサンプルで最終結果としています。

--------------------------------------------------------------
サンプルバッチファイル
--------------------------------------------------------------
rem 日付の比較をやってみたバッチ
@echo off
setlocal enabledelayedexpansion
rem ログの出力パス
set LOG=C:\temp\svc-test\svc.log
rem 今日の日付取得
set Today=%date:~0,4%-%date:~5,2%-%date:~8,2%
rem 判定用に月日だけ使う
set daymmdd=%date:~5,2%%date:~8,2%
rem ローテーション用の日付(1月1日は0101)
set rotateday=1122
rem 別の日付の取得処理
set yyyyMMdd=%date:/=%
echo %yyyyMMdd%
set MMdd=%yyyyMMdd:~4,2%%yyyyMMdd:~6,2%
echo %MMdd%

echo 最初の比較処理です。
echo %MMdd% EQU %rotateday%の比較
        if %MMdd% EQU %rotateday% (
                echo MMddとrotatedayは合致しました。
                goto secondif
        ) else (
                echo MMddとrotatedayは合致しません。
goto secondif
)

:secondif
echo 二回目の比較処理です。
echo %MMdd% EQU %rotateday%の比較
        if %%!MMdd!%% EQU %%!rotateday!%% (
                echo MMddとrotatedayは合致しました。
                goto THAADIF
        ) else (
                echo MMddとrotatedayは合致しません。
goto THAADIF
)

:THAADIF
echo 三回目の比較処理です。
echo %daymmdd% EQU %rotateday%の比較
        if %%!daymmdd!%% EQU %%!rotateday!%% (
                echo 合致したのでローテーション処理へ移動します。
                goto end
        ) else (
                echo 合致しないので、そのまま終了します。
goto end
)


:end
rem 後処理
set SERVICE=
set LOG=
set Today=
set MailPs=
set daymmdd=
set rotateday=
set yyyyMMdd=
set MMdd=
--------------------------------------------------------------

変数の入れ方を二通りで試しています。
一つは、"%daymmdd%"変数に「%date:~5,2%%date:~8,2%」と指定して、環境変数dateから直接setする変数、
もう一つは、"%MMdd%変数に入れているように、いったん別の変数に環境変数dateから数字だけ取り出したものを桁指定してsetした変数、
と言う具合に二通り用意して試してみました。

こうして用意した日付=数字を、変数名%rotateday%に入力した数字と比較して、合致するかどうかを確認します。
それぞれ、

if %MMdd% EQU %rotateday%
if %%!MMdd!%% EQU %%!rotateday!%%
if %%!daymmdd!%% EQU %%!rotateday!%%

の行が比較行です。変数の指定方法を変えて三回比較してその結果を確認してみます。

実行結果

実行してみた結果、以下のようになりました。
ただ、最初は「setlocal enabledelayedexpansion」を追加していなかったので、「if %MMdd% EQU %rotateday%」以外は合致しない結果になりました。

--------------------------------------------------------------

c:\temp\svc-test>dateで日付を検出.bat
20231122
1122
最初の比較処理です。
1122 EQU 1122の比較
MMddとrotatedayは合致しました。
二回目の比較処理です。
1122 EQU 1122の比較
MMddとrotatedayは合致しません。
三回目の比較処理です。
1122 EQU 1122の比較
合致しないので、そのまま終了します。

--------------------------------------------------------------

これは単純にミス。

「setlocal enabledelayedexpansion」を記載して有効化して実行してみると、以下のように変化しました。

※「setlocal enabledelayedexpansion」を有効にした実行結果

--------------------------------------------------------------

c:\temp\svc-test>dateで日付を検出.bat
20231122
1122
最初の比較処理です。
1122 EQU 1122の比較
MMddとrotatedayは合致しました。
二回目の比較処理です。
1122 EQU 1122の比較
MMddとrotatedayは合致しました。
三回目の比較処理です。
1122 EQU 1122の比較
合致したのでローテーション処理へ移動します。

--------------------------------------------------------------

なお、「setlocal enabledelayedexpansion」とは遅延環境変数と言って、変数を囲む%記号を「!」に変更することで、変数を読み込むタイミングを通常から変更させるという動きをします。

全部合致。単純に数字データと日付から取り出した数字を比較する時には、以下のパターンで合致させます。

  1. 変数に入れて、別の変数にもう一回入れる。※一回目入れてから、別の変数にもう一回入れると数字になるので確実に合致。
  2. 遅延環境変数「setlocal enabledelayedexpansion」を宣言し、変数を「%%!daynum!%%」のように指定する。

「setlocal enabledelayedexpansion」を使わない場合には(1)を使わないと誤判定する場合があります。

うーん、じゃあ、変数のdateから数字を取りだした後に、四桁に加工する必要が(今回のバッチ処理では)あるので、二つのset行で日付四桁を取り出すようにすればいいのか、という結論に至りました。