よく、ファイル名に日付を追加する場合などに利用します。
REM 文字操作 「:/=」 で = の直後を%にすることで「何もない」を表しますので
REM /=何もなし となり 「/を何もなしに置換」=削除 となる
set "yyyyMMdd=%date:/=%"
echo yyyyMMdd=%yyyyMMdd%
set "yyyy=%DATE:~0,4%"
set "MM=%DATE:~5.2%"
set "dd=%DATE:~8,2%"
REM %Time: =0 で (' '=0の意味で、スペースを0に置き換える) 桁合わせをする
REM これをしないと文字操作で桁ずれが発生する
set "T=%TIME: =0%"
set "HH=%T:~0,2%"
set "mm=%T:~3,2%"
set "ss=%T:~6,2%"
echo yyyy=%yyyy% MM=%MM% dd=%dd% HH=%HH% mm=%mm% ss=%ss%
date コマンドと同じフォーマットで現在の日付を取得できます。
REM Dateは、大文字でも小文字でもよさそうです。
echo %DATE%
結果
2023/01/28
time コマンドと同じフォーマットで現在の時刻を取得できます。※但し time /T とした場合は、HH:mm の形式でしか取得できません
REM Timeは、大文字でも小文字でもよさそうです。
echo %TIME%
結果
12:23:32.98
for /f "tokens=1-3 delims=/" %%a in ("%DATE%") do (
set "YEAR=%%a"
set "MONTH=%%b"
set "DAY=%%c"
)
echo D Year=%YEAR% Month=%MONTH% Day=%DAY%
for /f "tokens=1-4 delims=:." %%a in ("%TIME%") do (
set "HOUR=%%a"
set "MINUTSE=%%b"
set "SECOND=%%c"
set "SECOND100=%%d"
)
echo HOUR=%HOUR% MINUTSE=%MINUTSE% SECOND=%SECOND% SECOND/100=%SECOND100%
for /f "usebackq tokens=1-3 delims=/" %%a in (`DATE /T`) do (
set "YEAR=%%a"
set "MONTH=%%b"
set "DAY=%%c"
)
echo Year=%YEAR% Month=%MONTH% Day=%DAY%
結果
Year=2023 Month=01 Day=28
REM for文上の ~delims=:. "~ この部分が重要で、. と " の間は半角スペースを入れます、
REM これにより time コマンド実行後の戻り値 「現在の時刻: 16:57:30.61」の
REM 時間の前にある半角スペースが削除できます。(実際には、区切り文字として省かれます)
REM echo.は、改行をtimeコマンドに送ります。(注意点:echoとドットの間は空けない)
REM バッククォート内で|を使うには、^でエスケープします
REM for文は、最初の戻り行だけ処理したいので goto文で抜けます
for /f "usebackq tokens=1-5 delims=:. " %%a in (`echo.^|time`) do (
REM %%a には、「現在の時刻」という文字が入ります。
set "HOUR=%%b"
set "MINUTSE=%%c"
set "SECOND=%%d"
set "SECOND100=%%e"
goto :break
)
:break
echo HOUR=%HOUR% MINUTSE=%MINUTSE% SECOND=%SECOND% SECOND/100=%SECOND100%
わざわざ無理してこのようなプログラムする必要はないかもです。
結局のところ日付操作は、数値演算のようにいかず、バッチファイルでは、複雑な処理をコーディングしなければなりません。
バッチファイルを利用する目的が容易に複数処理を記述するというところであるので他に処理を頼んだほうが早いです。
Windowsでは、バッチに代わってPowershellを使うように施していますのでPowershell へ移行するかバッチファイル内でPowershellを読み出して利用するほうが良いようです。
Powershell を起動するのに
ポリシーをセットします。リモートアクセス権限レベルでないとスクリプトを実行できないため設定しておきます。
-ExecutionPolicy RemoteSigned
コマンドの記述。コマンドを直接記述する場合 -commandを用いて直接記述します。""で囲んだところがコマンドになります。
-command "((Get-date).AddDays(-1)).ToString('yyyy/MM/dd')"
ファイル上に記述してそれを読み出す場合 -file を用いて読み出します。今回は、使用してません。
-file ./sample.ps1
Powershellのコマンド Get-Date(Microsoftドキュメント) で DateTimeオブジェクト(Microsoftドキュメント)を取得します。
DateTimeオブジェクトは.NET(開発プラットフォーム)で定義されている構造体(およそオブジェクトのこと。ここではオブジェクトと書きます)です。
このオブジェクトには、いくつかのメソッドを持っていて日付の操作ができます。
DateTime.AddDays(Double)メソッド(Microsoftドキュメント):日の加算をし、加算後のDateTimeオブジェクトを返す。マイナス値を入れればマイナス加算=減算される
DateTime.ToString(String, IFormatProvider)メソッド(Microsoftドキュメント):Stringに記述した表示形式の文字列に変換しその文字列を返す。
DateTimeオブジェクトのその他プロパティ、メソッドの一覧(Microsoftドキュメント)
これを続けて記述すると…
(Get-Date).AddDays(-1).ToString('yyyy/MM/dd')
Get-Dateコマンドは、()で括らないと正しく値が出ないです。メソッドの実行ごとに()で括ったほうが確実かもしれません。
((Get-Date).AddDays(-1)).ToString('yyyy/MM/dd')
set "GETYESTERDAY=powershell -ExecutionPolicy RemoteSigned -command "(Get-date).AddDays(-1).ToString('yyyy/MM/dd')""
for /f "usebackq" %%i in (`%GETYESTERDAY%`) do (set YESTERDAY=%%i)
echo YESTERDAY=%YESTERDAY%
結果
YESTERDAY=2023/01/28
/なしで結合するなら以下の通りになります
set "GETYESTERDAY=powershell -ExecutionPolicy RemoteSigned -command "(Get-date).AddDays(-1).ToString('yyyyMMdd')""
for /f "usebackq" %%i in (`%GETYESTERDAY%`) do (set YESTERDAY=%%i)
echo YESTERDAY=%YESTERDAY%
結果
YESTERDAY=20230128
バッチファイルでは、数値の先頭に0が入っていると8進数と自動的に認識してしまいます。
そのため、0がついたまま計算させるとおかしな結果となり(8進数と分かって計算していれば良いですが。。。)ます。
日付データから一桁の月や、日を取出すと01、02など2桁目に0が入っていることが多く計算に困ります。
以下の方法でこの0を外して10進数の計算ができます
REM 0で始まる数値は8進数と認識されるため以下の計算を用いて0を除去する
REM 1を追加し2倍にする。そこから2を追加した値を引いて抽出
set "S_MONTH=01"
set /a "S_MONTH=1%S_MONTH%*2-2%S_MONTH%"
echo S_MONTH=%S_MONTH%