読者です 読者をやめる 読者になる 読者になる

雑記 - otherwise

最近はDQ10しかやっていないダメ技術者がちまちまと綴る雑記帳

DOS バッチの曜日算出(解説編)

雑談

R さんの質問にコメントで答えようとしていたら長くなりすぎたので記事化する試み。
ってか、先頭で日付取得しているのが紛らわしいんですね、きっと。 ^^;
なので、分割してみます。

REM 日付の抽出
set YEAR=%DATE:~0,4%
set MONTH=%DATE:~5,2%
set DAY=%DATE:~8,2%

ここで実行時の日付を取得していますが、この値はあくまでもテスト用です。<ここ重要

REM 算出の呼び出し
call :GETWEEK %YEAR% %MONTH% %DAY%

REM 結果表示
echo %ERRORLEVEL%
goto END
call :ラベル 引数

で、ラベル以降の処理を呼び出すことが出来ます。(今回、このバッチを書く際に、こんな事ができる事を知りました)
その際、 %1, %2, ... に引数に書いた値がセットされます。(通常の call と一緒)
そして、 exit 行があると、 call 元に戻ってきます。( /b で値をセットしておけば、 %errorlevel% にその値がセットされます)
この動きを利用して、サブルーチン呼び出しの様な事を実現している、と。

REM ----- 算出ロジック ここから -----
:GETWEEK
REM 引数の取得
set CHECKYEAR=%1
set CHECKMONTH=%2
set CHECKDAY=%3

REM 曜日の算出
if %CHECKMONTH% == 1 (
  set /A CHECKYEAR=%CHECKYEAR% - 1
  set /A CHECKMONTH=%CHECKMONTH% + 12
)
if %CHECKMONTH% == 2 (
  set /A CHECKYEAR=%CHECKYEAR% - 1
  set /A CHECKMONTH=%CHECKMONTH% + 12
)
set /A WEEK=(%CHECKYEAR% / 4 - %CHECKYEAR% / 100 + %CHECKYEAR% / 400 + (13 * %CHECKMONTH% + 8) / 5 + %DAY%) %% 7

exit /b %WEEK%
REM ----- 算出ロジック ここまで -----

このブロックがサブルーチン(の様なもの)の実体です。
ここで、 R さんの指摘にある「 CHECKEYAER 」には、 「引数の取得」で %1 を入れていますが、この %1 は call の第一引数の値(テストの部分で YEAR の値を設定している)になります。(テスト実行時はバッチ実行時の年)
R さんのご指摘で、ロジックを修正。ご指摘ありがとうございました。 m(_ _)m