バッチファイルでログファイルやバックアップファイルを作るとき、「backup_20250601_143022.zip」のように実行日時をファイル名に含めたい ケースは非常に多いです。しかし %DATE% や %TIME% をそのまま使うと、スラッシュやコロンがパス区切り文字と混在してエラーになったり、環境によって書式が変わったりと意外なところでハマります。
この記事では、日付・時刻の取得方法・文字列整形・ファイル名への埋め込みパターンを、コピーしてすぐ使えるサンプルコードとともに完全解説します。
この記事で学べること
%DATE% と %TIME% の書式と環境依存の注意点
日付・時刻文字列から年・月・日・時・分・秒を個別に取り出す 方法
backup_20250601_143022.log のようなタイムスタンプ付きファイル名 の作り方
曜日の取得・月初/月末判定など実務でよく使うパターン集
環境に依存しない安定した日付取得法 (wmic / PowerShell 活用)
%DATE% と %TIME% の基本
バッチファイルでは %DATE% と %TIME% という組み込み変数で現在の日付・時刻を取得できます。
コマンドプロンプト
echo %DATE%
:: 出力例(日本語Windows): 2025/06/01
echo %TIME%
:: 出力例: 14:30:22.45
%DATE% と %TIME% の書式(日本語Windows の場合)
変数
書式
出力例
文字数
%DATE%
YYYY/MM/DD
2025/06/01
10文字(固定)
%TIME%
H:MM:SS.cc
14:30:22.45
11文字(時が1桁の場合は空白あり)
注意(重要): %DATE% の書式はWindowsのロケール設定に依存 します。日本語Windowsでは YYYY/MM/DD ですが、英語Windowsでは Wed 06/01/2025 のように曜日付き・月日年順 になる場合があります。複数の環境で動かすバッチには後述の wmic や PowerShell を使った取得方法を推奨します。
年・月・日・時・分・秒を個別に取り出す
%DATE% と %TIME% から各要素を取り出すには、文字列の部分抽出 (%変数:~開始,文字数%)を使います。
extract_datetime.bat
@echo off
chcp 932 >nul
:: %DATE% = YYYY/MM/DD(日本語Windows)
set YYYY =%DATE:~0,4% :: 2025
set MM =%DATE:~5,2% :: 06
set DD =%DATE:~8,2% :: 01
:: %TIME% = H:MM:SS.cc(時が1桁のとき先頭がスペース)
:: スペースを 0 に置換してから切り出す
set T =%TIME: =0% :: スペース→0 に置換
set HH =%T:~0,2% :: 14
set MIN =%T:~3,2% :: 30
set SS =%T:~6,2% :: 22
echo 年: %YYYY% 月: %MM% 日: %DD%
echo 時: %HH% 分: %MIN% 秒: %SS%
pause
文字列部分抽出の構文
書き方
意味
%DATE%=2025/06/01 のとき
%DATE:~0,4%
0文字目から4文字
2025
%DATE:~5,2%
5文字目から2文字
06
%DATE:~8,2%
8文字目から2文字
01
%DATE:~-4%
末尾から4文字
0601(後ろから4文字)
タイムスタンプ付きファイル名の作り方
日付・時刻を取り出したら、ファイル名に使えない文字(/ : . スペース)を除去 して連結します。
基本パターン:YYYYMMDD_HHMMSS
timestamp_filename.bat
@echo off
chcp 932 >nul
:: 日付・時刻を取得して整形
set YYYY =%DATE:~0,4%
set MM =%DATE:~5,2%
set DD =%DATE:~8,2%
set T =%TIME: =0%
set HH =%T:~0,2%
set MIN =%T:~3,2%
set SS =%T:~6,2%
:: タイムスタンプ文字列を作成
set TIMESTAMP =%YYYY%%MM%%DD% _%HH%%MIN%%SS%
:: ファイル名に使う
echo 処理ログ > log_%TIMESTAMP% .txt
echo 作成したファイル: log_%TIMESTAMP% .txt
:: 出力例: log_20250601_143022.txt
pause
よく使うタイムスタンプの形式バリエーション
用途
変数の組み合わせ
出力例
日付のみ(最もシンプル)
%YYYY%%MM%%DD%
20250601
日付+時刻(標準)
%YYYY%%MM%%DD%_%HH%%MIN%%SS%
20250601_143022
ハイフン区切り(見やすい)
%YYYY%-%MM%-%DD%_%HH%-%MIN%-%SS%
2025-06-01_14-30-22
年月のみ(月次バックアップ)
%YYYY%%MM%
202506
ミリ秒まで含める
%YYYY%%MM%%DD%_%HH%%MIN%%SS%%T:~9,2%
20250601_14302245
実務パターン集
パターン1:ログファイルを日付ごとに自動切り替え
daily_log.bat
@echo off
chcp 932 >nul
setlocal EnableDelayedExpansion
set YYYY =%DATE:~0,4%
set MM =%DATE:~5,2%
set DD =%DATE:~8,2%
set T =%TIME: =0%
:: 今日の日付フォルダを作成してログを書き込む
set LOG_DIR =%~dp0logs\%YYYY%-%MM%-%DD%
set LOG_FILE =%LOG_DIR% app_%T:~0,2%%T:~3,2%%T:~6,2% .log
mkdir "%LOG_DIR% " 2>nul
echo [%DATE% %TIME% ] 処理開始 >> "%LOG_FILE% "
:: ---- メイン処理 ----
echo 処理中...
echo [%DATE% %TIME% ] 処理完了 >> "%LOG_FILE% "
echo ログ保存先: %LOG_FILE%
pause
パターン2:世代バックアップ(直近7日分を保持)
backup_7days.bat
@echo off
chcp 932 >nul
set YYYYMMDD =%DATE:~0,4%%DATE:~5,2%%DATE:~8,2%
set SRC =C:workdata
set BACKUP_DIR =D:ackup
:: 今日分のバックアップを作成
xcopy "%SRC% " "%BACKUP_DIR% %YYYYMMDD% " /E /I /Y >nul
echo バックアップ完了: %YYYYMMDD%
:: 8日以上前のバックアップを削除(forfiles でN日前のフォルダを削除)
forfiles /p "%BACKUP_DIR% " /d -8 /c "cmd /c if @isdir==TRUE rd /s /q @path" 2>nul
echo 古いバックアップを削除しました
pause
パターン3:処理時間(経過秒数)を計測する
elapsed_time.bat
@echo off
chcp 932 >nul
:: 開始時刻を取得(秒に変換)
set T =%TIME: =0%
set /A START = 1%T:~0,2% *3600 + 1%T:~3,2% *60 + 1%T:~6,2% - 1000000 - 10000 - 100
:: ---- メイン処理 ----
ping -n 3 127.0.0.1 >nul
:: 終了時刻を取得(秒に変換)
set T =%TIME: =0%
set /A END = 1%T:~0,2% *3600 + 1%T:~3,2% *60 + 1%T:~6,2% - 1000000 - 10000 - 100
set /A ELAPSED =%END% - %START%
echo 処理時間: %ELAPSED% 秒
pause
環境に依存しない安定した日付取得法
%DATE% はロケール設定によって書式が変わるため、複数の環境(英語OS・日本語OS)で動かすバッチ には以下の方法が安全です。
方法1:wmic を使う(Windows 7〜10対応)
date_wmic.bat
@echo off
chcp 932 >nul
:: wmic で YYYYMMDD を取得(ロケール非依存)
FOR /F "usebackq delims=" %%d IN (`wmic os get LocalDateTime /value ^| findstr LocalDateTime`) DO set DT =%%d
:: DT = LocalDateTime=20250601143022.000000+540 の形式
set DT =%DT:LocalDateTime=%
set YYYY =%DT:~0,4%
set MM =%DT:~4,2%
set DD =%DT:~6,2%
set HH =%DT:~8,2%
set MIN =%DT:~10,2%
set SS =%DT:~12,2%
echo %YYYY% /%MM% /%DD% %HH% :%MIN% :%SS%
pause
方法2:PowerShell を呼び出す(最もシンプル・Windows 7以降)
date_powershell.bat
@echo off
chcp 932 >nul
:: PowerShell で YYYYMMDD_HHmmss 形式を取得
FOR /F "usebackq delims=" %%t IN (`powershell -NoProfile -Command "Get-Date -Format 'yyyyMMdd_HHmmss'"`) DO set TIMESTAMP =%%t
echo タイムスタンプ: %TIMESTAMP%
echo ログ > log_%TIMESTAMP% .txt
echo 作成: log_%TIMESTAMP% .txt
pause
方法
メリット
デメリット
推奨場面
%DATE% / %TIME%
高速・依存ゼロ
ロケール依存
日本語環境のみで使う社内バッチ
wmic
ロケール非依存・bat のみで完結
Windows 11 では非推奨になりつつある
Windows 7〜10 の安定運用
PowerShell
シンプル・書式自由・最も確実
起動に数百msかかる
Windows 7以降・多環境対応・新規開発
よくあるトラブルと対処法
症状
原因
対処法
ファイル名にスラッシュが入ってエラー
%DATE%をそのままファイル名に使った
%DATE:~0,4%%DATE:~5,2%%DATE:~8,2% で区切り文字を除外
時刻が _4:03 のように1桁になる
%TIME% の時が1桁のとき先頭がスペース
set T=%TIME: =0% でスペースを0に置換してから使う
英語OSで %DATE% の書式が違う
ロケール依存で Wed 06/01/2025 形式になる
wmic または PowerShell を使う
タスクスケジューラで実行すると日付がずれる
タスク実行時の実行ユーザーのロケールが異なる
PowerShell 方式で取得する
FOR /F で wmic の出力に余分な文字が入る
wmic の出力に BOM や改行コードが含まれる場合がある
set DT=%DT:LocalDateTime=% で余分な文字列を除去
よくある質問(FAQ)
Q. %DATE%と%TIME%のフォーマットはどの設定によって変わりますか?
A. Windowsの地域設定(コントロールパネル→地域→形式)によって変わります。日本語設定では%DATE%は「2024/04/01」形式になります。スクリプトを別環境で動かす場合はwmic os get LocalDateTimeコマンドを使って固定フォーマット(yyyymmddHHMMSS形式)で取得する方が安全です。
Q. ミリ秒まで含むタイムスタンプを取得するにはどうすればよいですか?
A. バッチファイルの%TIME%は1/100秒まで(HH:MM:SS.CC形式)です。真のミリ秒はPowerShellで取得します:powershell -Command "(Get-Date).ToString('yyyyMMddHHmmssfff')"でミリ秒3桁まで含むタイムスタンプが得られます。
Q. ファイル名に日付を付けるとき、コロンやスラッシュを除去する方法は?
A. %DATE:/=_%でスラッシュをアンダースコアに、%TIME::=_%でコロンをアンダースコアに置換できます。または文字列のスライス(%DATE:~0,4%%DATE:~5,2%%DATE:~8,2%)でYYYYMMDD形式に整形する方法が確実です。スライス位置はecho %DATE%で実際の形式を確認してから決めます。
まとめ
日付・時刻のタイムスタンプ付きファイル名を作る基本手順は以下の通りです。
タイムスタンプ付きファイル名の最短テンプレート
@echo off
chcp 932 >nul
set T =%TIME: =0%
set TS =%DATE:~0,4%%DATE:~5,2%%DATE:~8,2% _%T:~0,2%%T:~3,2%%T:~6,2%
echo ログ開始 > log_%TS% .txt
:: → log_20250601_143022.txt が作成される
ポイント: 日本語Windows 固定の社内バッチなら %DATE%/%TIME% で十分です。複数環境・英語OSでの動作が必要な場合は PowerShell 方式 が最もシンプルで確実です。
よくある質問
❓ %DATE% で曜日を取得できますか? (クリックで開閉)
日本語Windowsの %DATE% は 2025/06/01 形式のみで曜日は含まれません。曜日を取得したい場合は PowerShell が便利です。
FOR /F "usebackq delims=" %%d IN (`powershell -NoProfile -Command "Get-Date -Format 'ddd'"`) DO set DOW=%%d
echo 今日の曜日: %DOW%
:: 出力例: Sun, Mon, Tue ... (ロケールにより日, 月, 火...)
❓ 昨日の日付や1週間前の日付を取得するにはどうすればいいですか? (クリックで開閉)
バッチファイル単体での日付計算は月をまたぐ場合など複雑になります。PowerShell で AddDays() を使う のが最も簡単です。
:: 昨日の日付を取得
FOR /F "usebackq delims=" %%d IN (`powershell -NoProfile -Command "(Get-Date).AddDays(-1).ToString('yyyyMMdd')"`) DO set YESTERDAY=%%d
echo 昨日: %YESTERDAY%
:: 7日前の日付を取得
FOR /F "usebackq delims=" %%d IN (`powershell -NoProfile -Command "(Get-Date).AddDays(-7).ToString('yyyyMMdd')"`) DO set WEEK_AGO=%%d
echo 1週間前: %WEEK_AGO%
❓ タスクスケジューラで実行したとき %DATE% の書式が変わる場合があります。なぜですか? (クリックで開閉)
タスクスケジューラはシステムアカウント(SYSTEM)や別ユーザーで実行されることがあり、そのユーザーのロケール設定が日本語環境と異なる 場合に書式が変わります。この問題を避けるには wmic または PowerShell で日付を取得するのが確実です。
関連するまとめページ