【bat】バッチファイルで曜日を判定して処理を制御する完全ガイド|wmic・%DATE%・平日/休日・複数曜日・時間帯組み合わせ・月末判定まで

【bat】バッチファイルで曜日を判定して処理を制御する完全ガイド|wmic・%DATE%・平日/休日・複数曜日・時間帯組み合わせ・月末判定まで bat

「月曜日だけバックアップを実行する」「平日のみ通知メールを送る」「土日は処理をスキップして月曜に繰り越す」——こういった曜日ベースのスケジュール制御はバッチファイルで実現できます。wmic による数値取得・%DATE% の文字列パース・PowerShell の DayOfWeek など複数の方法を実践コードで解説します。

この記事でわかること

  • wmic で曜日を数値(0〜6)で取得して if 条件で分岐する基本パターン
  • %DATE% の曜日文字列(月・火・水…)を使って wmic なしで判定する方法
  • 平日(月〜金)・休日(土日)をまとめて判定する方法
  • 「月・水・金のみ」など複数の特定曜日を OR 条件で処理する方法
  • 曜日と時間帯を組み合わせた高度な条件分岐
  • 月初・月末・第 N 週と曜日の組み合わせ判定
  • PowerShell の DayOfWeek 列挙体で曜日を判定する方法
スポンサーリンク

曜日判定の実装方式比較

方式 取得形式 ロケール依存 精度 実装難度
wmic DayOfWeek 数値(0=日〜6=土) なし(数値)
%DATE% 文字列パース 曜日文字列(月・火…) あり(日本語環境前提)
PowerShell DayOfWeek 英語文字列(Monday…) なし(英語固定)
PowerShell 数値変換 数値(0=日〜6=土) なし
方式の使い分け
wmic DayOfWeek が最も確実でロケール依存もなくおすすめです。%DATE% 方式は wmic が使えない環境や簡易スクリプトに向いていますが、日本語 Windows 専用になります。複雑な条件(月末の特定曜日など)は PowerShell と組み合わせると簡潔に書けます。

方法1:wmic で曜日を数値取得して判定する(基本・推奨)

wmic path win32_localtime get DayOfWeek /value で曜日を数値(0=日曜〜6=土曜)として取得します。ロケールに依存しないため環境を選ばない最も確実な方法です。

DayOfWeek 値 曜日 DayOfWeek 値 曜日
0 日曜日 4 木曜日
1 月曜日 5 金曜日
2 火曜日 6 土曜日
3 水曜日
weekday_wmic.bat: wmic で曜日を取得して特定曜日に処理を実行する
@echo off
setlocal

REM wmic で曜日を数値取得(0=日 1=月 2=火 3=水 4=木 5=金 6=土)
for /f "tokens=2 delims==" %%D in (
    'wmic path win32_localtime get DayOfWeek /value'
) do set DOW=%%D

REM 先頭・末尾の空白・改行を除去
set DOW=%DOW: =%

echo 今日の曜日コード: %DOW%

REM 月曜日(1)のみ実行
if "%DOW%"=="1" (
    echo 月曜日: バックアップを実行します
    REM ここにバックアップ処理を記述
) else (
    echo 今日は月曜日ではありません。スキップします
)

endlocal
wmic の出力に余分な空白・改行が含まれる問題
wmic の出力値は末尾に CR(キャリッジリターン)や空白が含まれることがあります。set DOW=%DOW: =% で空白を除去するか、for /f "tokens=2 delims==" %%D in ('...')tokens=2 で値部分だけを取り出す書き方が確実です。%DOW% が空になる場合は wmic の出力フォーマットをecho %DOW% で確認してください。
曜日名(文字列)として表示しながら判定するパターン
@echo off
setlocal enabledelayedexpansion

for /f "tokens=2 delims==" %%D in (
    'wmic path win32_localtime get DayOfWeek /value'
) do set DOW=%%D
set DOW=%DOW: =%

REM 数値 → 曜日名の変換テーブル
set "DAY_0=日曜日"
set "DAY_1=月曜日"
set "DAY_2=火曜日"
set "DAY_3=水曜日"
set "DAY_4=木曜日"
set "DAY_5=金曜日"
set "DAY_6=土曜日"

call set "DAY_NAME=%%DAY_%DOW%%%"
echo 今日は %DAY_NAME% (コード: %DOW%) です

if "%DOW%"=="1" echo 月曜: 週次レポートを生成します
if "%DOW%"=="5" echo 金曜: 週次バックアップを実行します
endlocal

方法2:%DATE% の曜日文字列で wmic なしに判定する

日本語 Windows では %DATE%2026/03/20(金) のような書式で返ります。このうち括弧内の曜日文字を取り出して比較することで、wmic を使わずに曜日を判定できます。

%DATE% から曜日文字を切り出して判定する
@echo off
setlocal

REM %DATE% 例: 2026/03/20(金)
REM 曜日は括弧内の1文字(例: 月 火 水 木 金 土 日)

REM %DATE% の長さから曜日位置を特定する(書式: YYYY/MM/DD(曜))
set "TODAY=%DATE%"

REM 括弧「(」の位置で切り出す
for /f "tokens=2 delims=()" %%W in ("%TODAY%") do set DOW_CHAR=%%W

echo 今日の曜日: %DOW_CHAR%

if "%DOW_CHAR%"=="月" echo 月曜日の処理を実行します
if "%DOW_CHAR%"=="金" echo 金曜日: 週次バックアップを実行します
if "%DOW_CHAR%"=="土" echo 土曜日のためスキップします & goto :eof
if "%DOW_CHAR%"=="日" echo 日曜日のためスキップします & goto :eof

endlocal
%DATE% の書式は OS の設定で変わることがある
Windows の地域設定によっては %DATE% の書式が異なります。たとえば 2026/03/20(曜日なし)の設定もあります。スクリプトを複数 PC で使用する場合は wmic 方式PowerShell 方式の方が安全です。本番環境では必ず echo %DATE% で書式を確認してください。

方法3:平日(月〜金)・休日(土日)をまとめて判定する

「平日のみ実行」「土日はスキップ」という条件は実務で最も多いパターンです。if %DOW% GEQ 1 if %DOW% LEQ 5 で平日範囲を判定できます。

weekday_check.bat: 平日/休日を判定して処理を分岐する
@echo off
setlocal

for /f "tokens=2 delims==" %%D in (
    'wmic path win32_localtime get DayOfWeek /value'
) do set DOW=%%D
set DOW=%DOW: =%

REM 平日判定(1=月〜5=金)
if %DOW% GEQ 1 if %DOW% LEQ 5 (
    echo [平日] 通常処理を実行します
    goto :DO_WORK
)

REM 休日(土=6 / 日=0)
echo [休日] 今日は土日のため処理をスキップします
echo スキップログ: %DATE% >> "C:\logs\skip.log"
exit /b 0

:DO_WORK
echo 業務処理を実行中...
REM ここに処理を記述
echo [完了] %DATE% %TIME% >> "C:\logs\run.log"
endlocal
平日か休日かをログに記録しながら実行/スキップを制御する実践版
@echo off
setlocal

set "LOGFILE=C:\logs\weekday_check.log"
if not exist "C:\logs" mkdir "C:\logs"

for /f "tokens=2 delims==" %%D in (
    'wmic path win32_localtime get DayOfWeek /value'
) do set DOW=%%D
set DOW=%DOW: =%

set "DAY_1=月" & set "DAY_2=火" & set "DAY_3=水"
set "DAY_4=木" & set "DAY_5=金" & set "DAY_6=土" & set "DAY_0=日"
call set "DAY_NAME=%%DAY_%DOW%%%"

if %DOW% GEQ 1 if %DOW% LEQ 5 (
    echo [%DATE% %TIME%] [平日/%DAY_NAME%] 実行 >> "%LOGFILE%"
    echo 平日 (%DAY_NAME%) のため処理を実行します
) else (
    echo [%DATE% %TIME%] [休日/%DAY_NAME%] スキップ >> "%LOGFILE%"
    echo 休日 (%DAY_NAME%) のためスキップします
)
endlocal

方法4:複数の特定曜日を OR 条件で処理する

「月・水・金のみ」「火・木のみ」のように飛び飛びの曜日を指定するには複数の if 条件を goto と組み合わせて OR 判定します。

multi_day.bat: 月・水・金のみ処理を実行する(OR条件)
@echo off
setlocal

for /f "tokens=2 delims==" %%D in (
    'wmic path win32_localtime get DayOfWeek /value'
) do set DOW=%%D
set DOW=%DOW: =%

REM 月(1) / 水(3) / 金(5) のいずれかなら処理を実行
set "RUN="
if "%DOW%"=="1" set "RUN=月曜日"
if "%DOW%"=="3" set "RUN=水曜日"
if "%DOW%"=="5" set "RUN=金曜日"

if defined RUN (
    echo [%RUN%] 処理を実行します
    REM ここに処理を記述
) else (
    echo 今日は対象曜日ではありません(実行対象: 月・水・金)
)
endlocal
実行対象曜日をリスト変数で管理して柔軟に設定変更できる版
@echo off
setlocal enabledelayedexpansion

REM 実行対象曜日リスト(数値: 0=日 1=月 2=火 3=水 4=木 5=金 6=土)
set "TARGET_DAYS=1 3 5"

for /f "tokens=2 delims==" %%D in (
    'wmic path win32_localtime get DayOfWeek /value'
) do set DOW=%%D
set DOW=%DOW: =%

set "MATCH="
for %%T in (%TARGET_DAYS%) do (
    if "!DOW!"=="%%T" set "MATCH=1"
)

if defined MATCH (
    echo 実行対象曜日 (DOW=%DOW%): 処理を実行
    REM ここに処理を記述
) else (
    echo 非対象曜日 (DOW=%DOW%): スキップ
)
endlocal
設定変数で曜日リストを管理するメリット
set "TARGET_DAYS=1 3 5" の数値を変更するだけで実行対象曜日を変えられます。1 2 3 4 5 にすれば平日のみ、6 0 にすれば週末のみになります。スクリプト本体を編集せずに設定ファイルや引数から受け取ることもできます。

方法5:曜日と時間帯を組み合わせた条件分岐

「平日の午前9時〜午後6時のみ実行」「月曜の深夜にバックアップ」のように曜日と時間帯を組み合わせた条件が必要な場合のパターンです。

weekday_time.bat: 平日の業務時間帯(9〜18時)のみ処理を実行する
@echo off
setlocal

for /f "tokens=2 delims==" %%D in (
    'wmic path win32_localtime get DayOfWeek /value'
) do set DOW=%%D
set DOW=%DOW: =%

REM 現在の時(Hour)を取得
for /f "tokens=2 delims==" %%H in (
    'wmic path win32_localtime get Hour /value'
) do set HOUR=%%H
set HOUR=%HOUR: =%

REM 平日(月〜金)かつ業務時間(9〜17時)か判定
set "IN_WINDOW="

if %DOW% GEQ 1 if %DOW% LEQ 5 (
    if %HOUR% GEQ 9 if %HOUR% LEQ 17 (
        set "IN_WINDOW=1"
    )
)

if defined IN_WINDOW (
    echo [業務時間内: 曜日=%DOW% 時刻=%HOUR%時] 処理を実行します
    REM ここに処理を記述
) else (
    echo [業務時間外: 曜日=%DOW% 時刻=%HOUR%時] スキップします
)
endlocal
月曜深夜(月曜 23〜25 時 = 火曜 0〜1 時)バックアップのパターン
@echo off
setlocal

REM 月曜深夜: 月曜 23:00〜翌火曜 01:00 の間にフルバックアップ
for /f "tokens=2 delims==" %%D in (
    'wmic path win32_localtime get DayOfWeek /value'
) do set DOW=%%D
for /f "tokens=2 delims==" %%H in (
    'wmic path win32_localtime get Hour /value'
) do set HOUR=%%H
set DOW=%DOW: =%
set HOUR=%HOUR: =%

REM 月曜の 23 時以降
set "BACKUP="
if "%DOW%"=="1" if %HOUR% GEQ 23 set "BACKUP=1"
REM または火曜の 0〜1 時
if "%DOW%"=="2" if %HOUR% LEQ 1 set "BACKUP=1"

if defined BACKUP (
    echo [月曜深夜バックアップ] 開始 %DATE% %TIME%
    REM ここにバックアップ処理
) else (
    echo バックアップ実行時間外
)
endlocal
wmic で Hour・Minute も取得できる
wmic path win32_localtime get Hour /value のようにHourMinuteSecondMonthDayも同じ書式で取得できます。時刻ベースのログ管理については実行時刻・経過時間をログに記録する完全ガイドも参照してください。

方法6:月初・月末・第 N 週と曜日を組み合わせて判定する

「月初の月曜日にだけ実行」「月末の金曜日にレポートを送信」のような月内の特定タイミングと曜日を組み合わせた判定パターンです。

month_begin.bat: 毎月1日の月曜日(または月初最初の月曜日)に実行する
@echo off
setlocal

for /f "tokens=2 delims==" %%D in (
    'wmic path win32_localtime get DayOfWeek /value'
) do set DOW=%%D
for /f "tokens=2 delims==" %%G in (
    'wmic path win32_localtime get Day /value'
) do set DAY=%%G
set DOW=%DOW: =%
set DAY=%DAY: =%

REM 月初最初の月曜日: 1〜7 日かつ月曜日(DOW=1)
set "RUN="
if "%DOW%"=="1" (
    if %DAY% GEQ 1 if %DAY% LEQ 7 set "RUN=1"
)

if defined RUN (
    echo [月初月曜] 月次処理を実行します (日付: %DAY%日)
    REM 月次レポート生成・データリセット等
) else (
    echo 月初月曜ではありません (DOW=%DOW% DAY=%DAY%)
)
endlocal
month_end.bat: 月末の金曜日(翌週が別月の金曜)を判定して実行する
@echo off
setlocal

for /f "tokens=2 delims==" %%D in (
    'wmic path win32_localtime get DayOfWeek /value'
) do set DOW=%%D
for /f "tokens=2 delims==" %%G in (
    'wmic path win32_localtime get Day /value'
) do set DAY=%%G
for /f "tokens=2 delims==" %%M in (
    'wmic path win32_localtime get Month /value'
) do set MONTH=%%M
set DOW=%DOW: =%
set DAY=%DAY: =%

REM 月末最後の金曜日: 25〜31 日かつ金曜日(DOW=5)
set "RUN="
if "%DOW%"=="5" (
    if %DAY% GEQ 25 set "RUN=1"
)

if defined RUN (
    echo [月末金曜] 月次締め処理 %MONTH%月%DAY%日
    REM 月次レポート送信・バックアップ等
) else (
    echo 月末金曜ではありません
)
endlocal
第 N 週の計算方法
第 N 週(例: 第2火曜日)は DAY の値から計算できます。第1週 = 1〜7日、第2週 = 8〜14日、第3週 = 15〜21日、第4週 = 22〜28日です。例: 第2火曜日 → DOW=2 かつ DAY GEQ 8 かつ DAY LEQ 14。日付処理の詳細は日付と時間をファイル名に挿入する方法も参照してください。

方法7:PowerShell の DayOfWeek で曜日を判定する

PowerShell の [datetime]::Today.DayOfWeek は英語の曜日名(Sunday, Monday, ..., Saturday)を返します。数値に変換する場合は [int] でキャストします。

PowerShell で曜日を取得してバッチ側の変数に返す
@echo off
setlocal

REM PowerShell で曜日を数値(0=日〜6=土)で取得
for /f %%D in (
    'powershell -NoProfile -Command "[int][datetime]::Today.DayOfWeek"'
) do set DOW=%%D

echo 曜日コード: %DOW%

if "%DOW%"=="1" echo 月曜日の処理を実行します
if "%DOW%"=="5" echo 金曜日の処理を実行します

endlocal
PowerShell で曜日・時刻・日付を一括取得して複合条件判定する
@echo off
setlocal

REM 一括取得: 曜日(0-6) / 時(0-23) / 月(1-12) / 日(1-31)
for /f "tokens=1-4" %%A in (
    'powershell -NoProfile -Command "$n = [datetime]::Now; ''#'' + [int]$n.DayOfWeek + '' '' + $n.Hour + '' '' + $n.Month + '' '' + $n.Day"'
) do (
    set DOW=%%B
    set HOUR=%%C
    set MON=%%D
    REM ※ tokens=1 はダミーの # のため %%A はスキップ
)

echo DOW=%DOW% HOUR=%HOUR% MONTH=%MON%

REM 平日の業務時間内か判定
set "OK="
if %DOW% GEQ 1 if %DOW% LEQ 5 if %HOUR% GEQ 9 if %HOUR% LEQ 17 set "OK=1"

if defined OK (
    echo [業務時間内] 処理を実行します
) else (
    echo [業務時間外/休日] スキップします
)
endlocal
PowerShell 版のメリット

  • [int][datetime]::Today.DayOfWeek は wmic と同じ 0=日〜6=土 の数値を返す
  • ロケールに依存せず英語環境・日本語環境どちらでも同じ値
  • 曜日・時・分・月・日を1回の PowerShell 呼び出しで一括取得できる
  • wmic より起動が速い(特に古い wmic は遅い場合がある)

タスクスケジューラとの使い分け

バッチ内曜日判定 vs タスクスケジューラ

観点 バッチ内で判定 タスクスケジューラで制御
設定場所 バッチファイル内 タスクスケジューラのGUI or schtasks
柔軟性 高(複合条件が書ける) 単純な曜日指定のみ
ログ 自前で実装 タスクスケジューラが自動記録
管理 バッチ編集のみでOK GUI or PowerShell で登録
推奨用途 複雑な条件(月末第N週など) 単純な曜日・時刻指定

「特定曜日のみ実行」程度であればタスクスケジューラのトリガーで設定する方がシンプルで確実です。複合条件(月末の月曜かつ業務時間内など)が必要な場合はバッチ内判定が有利です。タスクスケジューラへの登録方法はPC起動・ログオン時に自動実行する完全ガイドも参照してください。

まとめ

  • wmic DayOfWeek: 数値(0=日〜6=土)で取得。ロケール非依存で最も確実
  • %DATE% 文字列: 括弧内の曜日文字を切り出して判定。日本語 Windows 専用
  • 平日/休日: if %DOW% GEQ 1 if %DOW% LEQ 5 で平日判定。ログも忘れずに
  • 複数曜日 OR: set "TARGET_DAYS=1 3 5" のリスト変数 + for ループで柔軟に設定
  • 時間帯組み合わせ: wmic Hour も同様に取得して AND 条件を重ねる
  • 月初・月末・第N週: wmic Day の範囲チェックと組み合わせて判定
  • PowerShell: [int][datetime]::Today.DayOfWeek で高速・ロケール非依存

関連記事: PC起動・ログオン時に自動実行する完全ガイド / 実行時刻・経過時間をログに記録する完全ガイド / ログを出力する方法完全ガイド

よくある質問(FAQ)

Qwmic で取得した %DOW% が空になります。
Awmic の出力に余分な空白や CR が含まれると変数が空になることがあります。echo [%DOW%] で内容を確認してください。対策として set DOW=%DOW: =%(空白除去)を追加するか、for /f "tokens=2 delims==" %%D in ('wmic ... /value') do set DOW=%%Dtokens=2 delims== 書式で等号後の値だけを取り出してください。それでも空になる場合は PowerShell 方式に切り替えてください。
Q祝日(国民の祝日)も休日として判定したいです。
Aバッチ単体で祝日データを持つことはできません。実用的な方法は①祝日日付をテキストファイルに列挙して findstr で当日と照合する、②PowerShell からネット上の祝日 API(内閣府の CSV 等)を取得して判定する、の2つです。テキストファイル方式は毎年の更新が必要ですが、ネット接続不要で動作します。
Q曜日判定がうまくいかず毎日実行されてしまいます。
Aif "%DOW%"=="1" の比較で注意が必要なのは、%DOW% に空白や改行が含まれていて文字列が一致しないケースです。if %DOW% EQU 1(文字列ではなく数値比較)を使うと前後の空白を無視して比較できるので確実です。また echo %DOW% で実際の値を確認して、期待の値と一致しているかチェックしてください。
Q曜日に加えて月末かどうかも判定したいのですが、月によって末日が変わります。
Aバッチだけで月の末日を計算するのは複雑です(うるう年対応が必要)。PowerShell なら [datetime]::DaysInMonth($year, $month) でその月の日数を取得できます。$day -eq [datetime]::DaysInMonth($year, $month) で今日が月末かどうか判定できます。バッチから呼び出して変数に返す方法は本記事の方法7を参考にしてください。
Qタスクスケジューラで曜日を設定するだけではダメですか?
A単純な「毎週月曜日に実行」ならタスクスケジューラのトリガー設定だけで十分です。バッチ内で曜日判定が必要になるのは、「月末の金曜日」「第2火曜日かつ業務時間内」などタスクスケジューラでは表現できない複合条件が必要な場合です。シンプルなケースはタスクスケジューラに任せ、複雑なケースのみバッチ内で判定するのがメンテナンスしやすい設計です。