「バックアップファイルに日付を付けて世代管理したい」「ログファイルを日付付きで自動保存したい」「既存ファイルを一括でリネームして日付を差し込みたい」——バッチファイルで日付・時刻をファイル名に挿入する処理は自動化の基本です。本記事では %DATE%/%TIME% の文字列スライス から wmic・PowerShell を使った確実な取得方法、既存ファイルへの挿入・バックアップ・ログローテーションなどの実践パターンまで体系的に解説します。
- 日付・時刻を
YYYYMMDDやYYYY-MM-DD_HH-MM-SS形式で取得する方法 - 日付付きファイル名(新規・リネーム)を作成する方法
- 地域設定(ロケール)に左右されない確実な日付取得方法
- バックアップファイルに日付を付けて世代管理するパターン
- ログファイルを日付・時刻付きで自動生成するパターン
- 既存ファイルを一括で日付付きにリネームするパターン
方法の比較
| 方法 | 精度 | ロケール依存 | 特徴 |
|---|---|---|---|
%DATE% / %TIME% |
秒 | あり(注意) | 追加ツール不要・高速 |
wmic os get localdatetime |
ミリ秒 | なし | ロケールに左右されない・確実 |
PowerShell Get-Date |
ミリ秒 | なし | 柔軟なフォーマット・Win7以降 |
方法1: %DATE% と %TIME% を使う(最もシンプル)
日本語 Windows での日付・時刻フォーマット
日本語 Windows の %DATE% は通常 2025/03/14 形式です。
%TIME% は 10:05:30.12 形式(1桁の時は先頭スペースあり)です。
| 変数 | 値の例 | スライス | 取得内容 |
|---|---|---|---|
%DATE% |
2025/03/14 |
%DATE:~0,4% |
年(2025) |
%DATE% |
2025/03/14 |
%DATE:~5,2% |
月(03) |
%DATE% |
2025/03/14 |
%DATE:~8,2% |
日(14) |
%TIME% |
10:05:30.12 |
%TIME:~0,2% |
時(10) |
%TIME% |
9:05:30.12 |
%TIME:~0,2% |
時(先頭スペースあり→ 9) |
%TIME% |
10:05:30.12 |
%TIME:~3,2% |
分(05) |
%TIME% |
10:05:30.12 |
%TIME:~6,2% |
秒(30) |
日付・時刻付きファイル名を生成する基本
@echo off setlocal rem 日本語 Windows: %DATE% = 2025/03/14 %TIME% = 10:05:30.12 set YYYY=%DATE:~0,4% set MM=%DATE:~5,2% set DD=%DATE:~8,2% set HH=%TIME:~0,2% set MI=%TIME:~3,2% set SS=%TIME:~6,2% rem 時が1桁のとき先頭スペースを 0 に置換 set HH=%HH: =0% rem 形式例: 20250314_100530 set DATETIME=%YYYY%%MM%%DD%_%HH%%MI%%SS% echo DATETIME=%DATETIME% rem ファイル名に使う例 set FILENAME=report_%DATETIME%.txt echo ファイル名: %FILENAME% endlocal
%TIME% の時刻が1桁(例: 9時)のとき、%TIME:~0,2% は 9(先頭スペース)になります。set HH=%HH: =0% でスペースを 0 に置換すると 09 になります。
よく使う日付フォーマット一覧
@echo off setlocal set YYYY=%DATE:~0,4% set MM=%DATE:~5,2% set DD=%DATE:~8,2% set HH=%TIME:~0,2% set MI=%TIME:~3,2% set SS=%TIME:~6,2% set HH=%HH: =0% rem ファイル名に使いやすい形式(区切りなし) set FMT1=%YYYY%%MM%%DD%_%HH%%MI%%SS% echo FMT1: %FMT1% → backup_20250314_100530.zip rem 日付のみ(区切りなし) set FMT2=%YYYY%%MM%%DD% echo FMT2: %FMT2% → log_20250314.txt rem ハイフン区切り set FMT3=%YYYY%-%MM%-%DD% echo FMT3: %FMT3% → report_2025-03-14.csv rem 日時をフル表示(人が読みやすい形式) set FMT4=%YYYY%-%MM%-%DD%_%HH%-%MI%-%SS% echo FMT4: %FMT4% → output_2025-03-14_10-05-30.txt endlocal
方法2: wmic で確実に日付取得(ロケール非依存・推奨)
%DATE% は地域設定や OS の言語設定に依存するため、異なる PC で実行するとフォーマットが変わる場合があります。wmic を使うと ロケールに関係なく常に同じ形式(20250314105030.000000+540)で取得できます。
wmic で日付を取得する基本
@echo off
setlocal
rem wmic の出力形式: 20250314105030.000000+540
for /f "tokens=2 delims==" %%I in ('wmic os get localdatetime /value') do set DT=%%I
set YYYY=%DT:~0,4%
set MM=%DT:~4,2%
set DD=%DT:~6,2%
set HH=%DT:~8,2%
set MI=%DT:~10,2%
set SS=%DT:~12,2%
set DATETIME=%YYYY%%MM%%DD%_%HH%%MI%%SS%
echo DATETIME=%DATETIME%
rem ファイル名に使う
set FILENAME=backup_%DATETIME%.zip
echo ファイル名: %FILENAME%
endlocal
wmic のスライス一覧
| スライス | 取得内容 | 例 |
|---|---|---|
%DT:~0,4% |
年 | 2025 |
%DT:~4,2% |
月 | 03 |
%DT:~6,2% |
日 | 14 |
%DT:~8,2% |
時 | 10 |
%DT:~10,2% |
分 | 05 |
%DT:~12,2% |
秒 | 30 |
%DT:~15,6% |
マイクロ秒 | 000000 |
方法3: PowerShell Get-Date(柔軟なフォーマット指定)
PowerShell の Get-Date を使うと .NET のフォーマット文字列 で自由に日付フォーマットを指定できます。Windows 7 以降で利用可能です。
@echo off
setlocal
rem PowerShell で日付を取得(形式: 20250314_100530)
for /f %%D in ('powershell -NoProfile -Command "Get-Date -Format yyyyMMdd_HHmmss"') do set DATETIME=%%D
echo DATETIME=%DATETIME%
set FILENAME=report_%DATETIME%.txt
echo ファイル名: %FILENAME%
endlocal
PowerShell フォーマット文字列の例
| フォーマット | 出力例 | 用途 |
|---|---|---|
yyyyMMdd_HHmmss |
20250314_100530 | ファイル名(定番) |
yyyyMMdd |
20250314 | 日付のみ |
yyyy-MM-dd |
2025-03-14 | ハイフン区切り |
yyyy-MM-dd_HH-mm-ss |
2025-03-14_10-05-30 | ハイフン区切り日時 |
HHmmss |
100530 | 時刻のみ |
PowerShell の
Get-Date -Format では大文字・小文字で意味が変わります。HH = 24時間制(00〜23)、hh = 12時間制(01〜12)MM = 月、mm = 分 ←混同しやすいので注意
方法4: 既存ファイルに日付を挿入してリネーム
既存ファイルの先頭に日付を付加
@echo off
setlocal enabledelayedexpansion
set "TARGET=C:workdata"
for /f %%D in ('powershell -NoProfile -Command "Get-Date -Format yyyyMMdd"') do set DATESTR=%%D
set COUNT=0
for %%f in ("%TARGET%*.*") do (
rem 元のファイル名
set "OLD=%%~nxf"
set "NEW=%DATESTR%_%%~nxf"
rem 既に日付プレフィックスが付いていたらスキップ
echo !OLD! | findstr /b /c:"%DATESTR%" >nul
if not errorlevel 1 (
echo [SKIP] !OLD!
) else (
ren "%%~ff" "!NEW!"
if not errorlevel 1 (
echo [OK] !OLD! → !NEW!
set /a COUNT+=1
)
)
)
echo.
echo 完了: !COUNT! ファイルをリネームしました
endlocal
既存ファイルの末尾(拡張子前)に日付を挿入
@echo off
setlocal enabledelayedexpansion
set "TARGET=C:workdata"
for /f %%D in ('powershell -NoProfile -Command "Get-Date -Format yyyyMMdd_HHmmss"') do set DATESTR=%%D
for %%f in ("%TARGET%*.*") do (
rem %%~nf = 名前のみ %%~xf = 拡張子(ドット含む)
set "NEW=%%~nf_%DATESTR%%%~xf"
ren "%%~ff" "!NEW!"
echo [OK] %%~nxf → !NEW!
)
endlocal
実践例A: バックアップファイルに日付を付けて世代管理
毎日実行してバックアップを日付付きで保存し、古い世代を自動削除するパターンです。
@echo off
setlocal enabledelayedexpansion
set "SRC=C:workdata"
set "BAK=C:ackup"
set KEEP_DAYS=7
rem 日付取得(wmic で確実に)
for /f "tokens=2 delims==" %%I in ('wmic os get localdatetime /value') do set DT=%%I
set YYYY=%DT:~0,4%
set MM=%DT:~4,2%
set DD=%DT:~6,2%
set HH=%DT:~8,2%
set MI=%DT:~10,2%
set SS=%DT:~12,2%
set DATESTR=%YYYY%%MM%%DD%_%HH%%MI%%SS%
rem バックアップ先フォルダを作成
if not exist "%BAK%" mkdir "%BAK%"
rem バックアップ実行
set "BAKFILE=%BAK%ackup_%DATESTR%.zip"
echo バックアップ開始: %DATE% %TIME%
powershell -NoProfile -Command "Compress-Archive -Path %SRC%* -DestinationPath %BAKFILE% -Force"
if exist "%BAKFILE%" (
echo [OK] バックアップ作成: %BAKFILE%
) else (
echo [ERROR] バックアップ失敗
exit /b 1
)
rem KEEP_DAYS 日以上前のバックアップを削除
echo.
echo %KEEP_DAYS% 日以上前のバックアップを削除中...
forfiles /p "%BAK%" /m "backup_*.zip" /d -%KEEP_DAYS% /c "cmd /c echo 削除: @file && del @path" 2>nul
echo 完了: %DATE% %TIME%
endlocal
実践例B: ログファイルに日付・時刻付きで出力
処理結果を日付付きログファイルに記録し、日別・時刻別に管理するパターンです。
@echo off
setlocal enabledelayedexpansion
set "LOGDIR=C:logs"
rem 日付取得
for /f "tokens=2 delims==" %%I in ('wmic os get localdatetime /value') do set DT=%%I
set YYYY=%DT:~0,4%
set MM=%DT:~4,2%
set DD=%DT:~6,2%
set HH=%DT:~8,2%
set MI=%DT:~10,2%
set SS=%DT:~12,2%
rem ログファイルは日別(例: app_20250314.log)
if not exist "%LOGDIR%" mkdir "%LOGDIR%"
set "LOGFILE=%LOGDIR%app_%YYYY%%MM%%DD%.log"
rem ログ出力用マクロ(日時プレフィックス付き)
set "LOG=echo [%YYYY%-%MM%-%DD% %HH%:%MI%:%SS%]"
%LOG% 処理開始 >> "%LOGFILE%"
rem === ここに実際の処理を記述 ===
%LOG% ステップ1: データ読み込み >> "%LOGFILE%"
rem 処理1...
%LOG% ステップ2: データ変換 >> "%LOGFILE%"
rem 処理2...
%LOG% 処理完了 >> "%LOGFILE%"
echo ログ: %LOGFILE%
endlocal
実践例C: 日付別フォルダを自動作成してファイルを振り分け
処理したファイルを日付別フォルダに自動で振り分けるパターンです。
@echo off
setlocal enabledelayedexpansion
set "INPUT=C:workdata"
set "OUTPUT=C:ackuparchive"
for /f %%D in ('powershell -NoProfile -Command "Get-Date -Format yyyy-MM-dd"') do set TODAY=%%D
rem 今日の日付フォルダを作成
set "DEST=%OUTPUT%\%TODAY%"
if not exist "%DEST%" mkdir "%DEST%"
set COUNT=0
rem INPUT フォルダのファイルを今日のフォルダに移動
for %%f in ("%INPUT%*.*") do (
move "%%~ff" "%DEST%" >nul
if not errorlevel 1 (
echo [OK] %%~nxf → %DEST%
set /a COUNT+=1
)
)
echo.
echo 完了: !COUNT! ファイルを %DEST% に移動しました
endlocal
実践例D: タスクスケジューラ向け・完全無人実行ログ付きバッチ
タスクスケジューラから実行することを想定した、日時付きログ・エラー処理・終了コード対応の完全版です。
@echo off
setlocal enabledelayedexpansion
rem 日付取得(wmic で確実に)
for /f "tokens=2 delims==" %%I in ('wmic os get localdatetime /value') do set DT=%%I
set YYYY=%DT:~0,4%
set MM=%DT:~4,2%
set DD=%DT:~6,2%
set HH=%DT:~8,2%
set MI=%DT:~10,2%
set SS=%DT:~12,2%
set DATESTR=%YYYY%%MM%%DD%_%HH%%MI%%SS%
set "LOGFILE=%~dp0run_%YYYY%%MM%%DD%.log"
echo [%YYYY%-%MM%-%DD% %HH%:%MI%:%SS%] === 処理開始 === >> "%LOGFILE%"
rem --- 処理1 ---
echo [%YYYY%-%MM%-%DD% %HH%:%MI%:%SS%] 処理1開始 >> "%LOGFILE%"
rem ここに処理を記述
if errorlevel 1 (
echo [%YYYY%-%MM%-%DD% %HH%:%MI%:%SS%] [ERROR] 処理1失敗 >> "%LOGFILE%"
exit /b 1
)
rem --- バックアップ作成 ---
set "BAKFILE=C:ackupdata_%DATESTR%.zip"
echo [%YYYY%-%MM%-%DD% %HH%:%MI%:%SS%] バックアップ作成: %BAKFILE% >> "%LOGFILE%"
echo [%YYYY%-%MM%-%DD% %HH%:%MI%:%SS%] === 処理完了 === >> "%LOGFILE%"
endlocal
exit /b 0
よくある落とし穴
落とし穴1: %DATE% のフォーマットが地域設定で変わる
rem 日本語 Windows: %DATE% = 2025/03/14
rem 英語 Windows: %DATE% = Fri 03/14/2025
rem → スライス位置がずれてしまう
rem 地域に左右されない方法1: wmic を使う
for /f "tokens=2 delims==" %%I in ('wmic os get localdatetime /value') do set DT=%%I
rem 地域に左右されない方法2: PowerShell を使う
for /f %%D in ('powershell -NoProfile -Command "Get-Date -Format yyyyMMdd_HHmmss"') do set DT=%%D
落とし穴2: %TIME% の時刻が1桁のときスペースが入る
rem 9:00 の場合: %TIME% = " 9:00:00.00"(先頭スペース) rem %TIME:~0,2% は " 9"(スペース付き)になり、ファイル名に使えない rem 対策: スペースを 0 に置換する set HH=%TIME:~0,2% set HH=%HH: =0% rem 結果: "09" になる
落とし穴3: ファイル名に使えない文字が日付に含まれる
rem NG: スラッシュや コロンはファイル名に使えない rem %DATE% = 2025/03/14 → ファイル名に使うとエラー set FILENAME=log_%DATE%.txt ← スラッシュが含まれてエラー rem OK: スライスで数値のみ取り出して連結する set YYYY=%DATE:~0,4% set MM=%DATE:~5,2% set DD=%DATE:~8,2% set FILENAME=log_%YYYY%%MM%%DD%.txt
落とし穴4: setlocal enabledelayedexpansion が必要な場面
rem ループ内で日付変数を更新したり !VAR! を使う場合は setlocal enabledelayedexpansion が必要 rem NG: ループ内でカウンタを更新できない @echo off setlocal set COUNT=0 for %%f in (*.txt) do set /a COUNT+=1 echo 件数: %COUNT% ← ループ内の更新が反映されない rem OK: @echo off setlocal enabledelayedexpansion set COUNT=0 for %%f in (*.txt) do set /a COUNT+=1 echo 件数: !COUNT!
落とし穴5: wmic が廃止予定(Windows 11 の新環境に注意)
rem Windows 11 の一部エディションで wmic が将来的に廃止される可能性がある
rem 現時点(2025年)では使用可能だが、長期運用するスクリプトは PowerShell を推奨
rem PowerShell で代替:
for /f %%D in ('powershell -NoProfile -Command "Get-Date -Format yyyyMMdd_HHmmss"') do set DT=%%D
よくある質問(FAQ)
バッチファイル単体での日付計算は複雑です。PowerShell を使うのが確実です。
rem 昨日の日付
for /f %%D in ('powershell -NoProfile -Command "(Get-Date).AddDays(-1).ToString(''yyyyMMdd'')"') do set YESTERDAY=%%D
echo 昨日: %YESTERDAY%
rem 明日の日付
for /f %%D in ('powershell -NoProfile -Command "(Get-Date).AddDays(1).ToString(''yyyyMMdd'')"') do set TOMORROW=%%D
echo 明日: %TOMORROW%
文字列として組み立てるだけです。
@echo off
setlocal
for /f %%D in ('powershell -NoProfile -Command "Get-Date -Format yyyyMMdd_HHmmss"') do set DT=%%D
rem "report_2025年03月14日.txt" のような形式
set FNAME=data_%DT%_backup.zip
echo %FNAME%
endlocal
forfiles コマンドで日数指定削除ができます。
rem KEEP_DAYS 日以上前の .zip ファイルを削除 set KEEP_DAYS=7 forfiles /p "C:ackup" /m "backup_*.zip" /d -%KEEP_DAYS% /c "cmd /c del @path" 2>nul echo %KEEP_DAYS% 日以上前のバックアップを削除しました
YYYYMMDD 形式にするとファイル名の辞書順とそのまま日付順が一致します。
YYYY-MM-DD 形式も同様です。DD-MM-YYYY や MM/DD/YYYY はソートが崩れるため避けてください。
rem ◎ ソート順と日付順が一致する形式 set FNAME=log_20250314_100530.txt ← yyyyMMdd_HHmmss rem ✕ ソートが崩れる形式 set FNAME=log_14-03-2025.txt ← DD-MM-YYYY set FNAME=log_03-14-2025.txt ← MM-DD-YYYY
タスクスケジューラと組み合わせます。バッチファイル側では日付付きログファイル名を生成し、タスクスケジューラで毎日実行するよう設定します。
rem バッチファイル内(タスクスケジューラから実行想定)
for /f %%D in ('powershell -NoProfile -Command "Get-Date -Format yyyyMMdd"') do set TODAY=%%D
set "LOGFILE=C:logsdaily_%TODAY%.log"
echo 実行開始: %DATE% %TIME% >> "%LOGFILE%"
rem 処理...
echo 実行完了: %DATE% %TIME% >> "%LOGFILE%"
まとめ
| 目的 | 推奨方法 |
|---|---|
| シンプルに日付取得(日本語環境) | %DATE:~0,4%%DATE:~5,2%%DATE:~8,2% |
| ロケールに依存しない確実な取得 | wmic os get localdatetime |
| 柔軟なフォーマット指定 | PowerShell Get-Date -Format yyyyMMdd_HHmmss |
| 1桁の時刻にゼロ埋め | set HH=%HH: =0%(スペース→0置換) |
| バックアップ世代管理 | 日付付きファイル名 + forfiles で古いファイル削除 |
| ログの日別管理 | 日付をファイル名に入れて毎回 >> 追記 |
| ソート順と一致させる | YYYYMMDD または YYYY-MM-DD 形式を使う |
ファイルの拡張子変換については ファイルの拡張子を一括変換する方法 を、ファイル名のプレフィックス付加は ファイル名の先頭にフォルダ名を付ける方法 も合わせて参照してください。
