どこでも使う日付取得を汎用バッチ化する
日付を取得して、その前月とか翌月とかが欲しいときありあすよね。会社で会計処理するようなときには、前月末締めで前月末って具体的に何月何日? なんてことです。
どこでも欲しくなるような機能ですよね。それなら、汎用バッチ化して、それを呼べばすっきりするし、共通化もできます。
汎用バッチと言っているのは、Windows や DOS にそのような「汎用バッチ」と言うものがあるのではないのですが、バッチから汎用バッチを呼んで、各変数に日付をセットしてもらおうというものです。この考え方は、日付以外の他の機能にもあてはまります。例えば曜日を月~日で欲しいなんて場合も汎用化しておけば、それを呼べばいいだけになります。
百聞は一見に如かず、まずは見てみましょう。
サンプルコード dategettest.bat
@echo off call dateget.bat echo 年 月 0付月 日 0付日 末日 echo 前月 %Lyyyy% %Lmm% %LZmm% %Ldd% %LZdd% %LddL% echo 当月 %yyyy% %mm% %Zmm% %dd% %Zdd% %ddL% echo 翌月 %Nyyyy% %Nmm% %NZmm% %Ndd% %NZdd% %NddL% pause
4行目にかいてある “dateget.bat” と言うのが今回説明する汎用バッチです。このサンプルコードは、その汎用バッチを使う側のものです。汎用バッチを使う側は、”call dateget.bat” と1行書くだけで、次の値が得られます。
- 現在の年、月、月が1桁の場合に0を先頭に付けたもの、日、日が1桁の場合に0を先頭に付けたもの、末日
- 翌月の年、月、月が1桁の場合に0を先頭に付けたもの、日、日が1桁の場合に0を先頭に付けたもの、末日
- 前月の年、月、月が1桁の場合に0を先頭に付けたもの、日、日が1桁の場合に0を先頭に付けたもの、末日
全部で 18個の値を取得できます。実際に実行してみましょう。
実行結果(実行日:2016/2/4)
年 月 0付月 日 0付日 末日 前月 2016 1 01 4 04 31 当月 2016 2 02 4 04 29 翌月 2016 3 03 4 04 31
うるう年の処理も入っています。実行日が2016年2月4日で、その年はうるう年なので、2月は29日まであります。それで、当月の末日は29となっています。
実行結果(実行日:2018/1/21)
年 月 0付月 日 0付日 末日 前月 2017 12 12 21 21 31 当月 2018 1 01 21 21 31 翌月 2018 2 02 21 21 28
年跨りの処理も入っています。実行日が2018年1月21日だと、その前月は、2018年12月になります。
実行結果(実行日:2018/5/31)
年 月 0付月 日 0付日 末日 前月 2018 4 04 30 30 30 当月 2018 5 05 31 31 31 翌月 2018 6 06 30 30 30
前月同日、翌月同日が存在しない場合は、一番近い日:末日が設定されます。実行日が2018年5月31日の場合、前月4月と翌月6月はそれぞれ30日までしかないので、同日も末日も同じ30日が設定されます。
汎用バッチ dateget.bat
では、汎用バッチの方をみ見てみましょう。
@echo off rem 現在の日付けを取得し、各種日付けを求め変数に入れる rem 求める変数一覧 rem 年 0無月 0付月 0無日 0付日 末日 rem 前月 Lyyyy Lmm LZmm Ldd LZdd LddL rem 当月 yyyy mm Zmm dd Zdd ddL rem 翌月 Nyyyy Nmm NZmm Ndd NZdd NddL rem Z を含む変数で数値が1桁の場合、先頭に 0 が付く rem ************* 現在の日付を取得 **************************************** rem 日付をYYYY/MM/DD 形式で結果は環境変数 orgdate へ返す。 for /F "tokens=1" %%a in ('date /t') do set orgdate=%%a rem ■ デバッグ用 rem set orgdate=2018/01/21 rem *********************************************************************** rem ************* 当月の変数生成 ****************************************** rem *********************************************************************** rem ***** 現在年月日(yyyy mm dd)を orgdate(YYYY/MM/DD) から求める rem 年月日の分割 set yyyy=%orgdate:~0,4% set mm=%orgdate:~5,2% set dd=%orgdate:~8,2% rem ***** 月日の数値化(8進数対策) set /a mm=1%mm%-100 set /a dd=1%dd%-100 rem ***** うるう年判定 set UYYYY=%yyyy% rem うるう年であれば2月に足す日数 set Udd=0 rem 年が4で割り切れるか set /a U1=%UYYYY% %% 4 rem 年が100で割り切れるか set /a U2=%UYYYY% %% 100 rem 年が400で割り切れるか set /a U3=%UYYYY% %% 400 if %U1%==0 ( rem 年が4で割り切れると一応うるう年である set Udd=1 rem 4で割り切れても、100で割り切れて、400で割り切れないとうるう年ではない if %U2%==0 if not %U3%==0 ( set Udd=0 ) ) rem ***** 末日を求める set ddL= if %mm%==1 (set ddL=31) if %mm%==2 (set ddL=28) if %mm%==2 (set /a ddL=%ddL% + %Udd%) if %mm%==3 (set ddL=31) if %mm%==4 (set ddL=30) if %mm%==5 (set ddL=31) if %mm%==6 (set ddL=30) if %mm%==7 (set ddL=31) if %mm%==8 (set ddL=31) if %mm%==9 (set ddL=30) if %mm%==10 (set ddL=31) if %mm%==11 (set ddL=30) if %mm%==12 (set ddL=31) rem ***** Z 付き変数の処理 一桁の月、日の先頭に0を付ける set Zmm=0%mm% set Zmm=%Zmm:~-2% set Zdd=0%dd% set Zdd=%Zdd:~-2% rem *********************************************************************** rem ************* 前月の変数生成 ****************************************** rem *********************************************************************** rem 前月 Lyyyy Lmm LZmm Ldd LZdd LddL rem ***** 前月の年月(Lyyyy Lmm)を求める set Lyyyy=%yyyy% set /a Lmm=%mm%-1 rem 年跨り処理 現在1月 → 前月は12月 if %Lmm% EQU 0 set Lmm=12&&set /a Lyyyy=%yyyy%-1 rem ***** うるう年判定 set UYYYY=%Lyyyy% rem うるう年であれば2月に足す日数 set Udd=0 rem 年が4で割り切れるか set /a U1=%UYYYY% %% 4 rem 年が100で割り切れるか set /a U2=%UYYYY% %% 100 rem 年が400で割り切れるか set /a U3=%UYYYY% %% 400 if %U1%==0 ( rem 年が4で割り切れると一応うるう年である set Udd=1 rem 4で割り切れても、100で割り切れて、400で割り切れないとうるう年ではない if %U2%==0 if not %U3%==0 ( set Udd=0 ) ) rem ***** 前月の末日(LddL)を求める if %Lmm%==1 (set LddL=31) if %Lmm%==2 (set LddL=28) if %Lmm%==2 (set /a LddL=%LddL% + %Udd%) if %Lmm%==3 (set LddL=31) if %Lmm%==4 (set LddL=30) if %Lmm%==5 (set LddL=31) if %Lmm%==6 (set LddL=30) if %Lmm%==7 (set LddL=31) if %Lmm%==8 (set LddL=31) if %Lmm%==9 (set LddL=30) if %Lmm%==10 (set LddL=31) if %Lmm%==11 (set LddL=30) if %Lmm%==12 (set LddL=31) rem ***** 前月の同日(Ldd)を求める set Ldd=%dd% rem 前月同日が、末日を超える場合は末日に修正 if %LddL% lss %Ldd% (set Ldd=%LddL%) rem ***** Z 付き変数の処理 一桁の月、日の先頭に0を付ける set LZmm=0%Lmm% set LZmm=%LZmm:~-2% set LZdd=0%Ldd% set LZdd=%LZdd:~-2% rem *********************************************************************** rem ************* 翌月の変数生成 ****************************************** rem *********************************************************************** rem 翌月 Nyyyy Nmm NZmm Ndd NZdd NddL rem ***** 翌月の年月(Nyyyy Nmm)を求める set Nyyyy=%yyyy% set /a Nmm=%mm%+1 rem 年跨り処理 現在1月 → 翌月は12月 if %Nmm% EQU 13 set Nmm=1&&set /a Nyyyy=%yyyy%+1 rem ***** うるう年判定 set UYYYY=%Nyyyy% rem うるう年であれば2月に足す日数 set Udd=0 rem 年が4で割り切れるか set /a U1=%UYYYY% %% 4 rem 年が100で割り切れるか set /a U2=%UYYYY% %% 100 rem 年が400で割り切れるか set /a U3=%UYYYY% %% 400 if %U1%==0 ( rem 年が4で割り切れると一応うるう年である set Udd=1 rem 4で割り切れても、100で割り切れて、400で割り切れないとうるう年ではない if %U2%==0 if not %U3%==0 ( set Udd=0 ) ) rem ***** 翌月の末日(NddL)を求める if %Nmm%==1 (set NddL=31) if %Nmm%==2 (set NddL=28) if %Nmm%==2 (set /a NddL=%NddL% + %Udd%) if %Nmm%==3 (set NddL=31) if %Nmm%==4 (set NddL=30) if %Nmm%==5 (set NddL=31) if %Nmm%==6 (set NddL=30) if %Nmm%==7 (set NddL=31) if %Nmm%==8 (set NddL=31) if %Nmm%==9 (set NddL=30) if %Nmm%==10 (set NddL=31) if %Nmm%==11 (set NddL=30) if %Nmm%==12 (set NddL=31) rem ***** 翌月の同日(Ndd)を求める set Ndd=%dd% rem 翌月同日が、末日を超える場合は末日に修正 if %NddL% lss %Ndd% (set Ndd=%NddL%) rem ***** Z 付き変数の処理 一桁の月、日の先頭に0を付ける set NZmm=0%Nmm% set NZmm=%NZmm:~-2% set NZdd=0%Ndd% set NZdd=%NZdd:~-2% rem echo ■前月 %Lyyyy% %Lmm% %LZmm% %Ldd% %LZdd% %LddL% rem echo ■当月 %yyyy% %mm% %Zmm% %dd% %Zdd% %ddL% rem echo ■翌月 %Nyyyy% %Nmm% %NZmm% %Ndd% %NZdd% %NddL%
中身はよく読んでもらえばコメントも書いてあるので、理解していただけるかなと思いますが、汎用バッチなので、そのままコピってまずは使ってください。
使い方は、最初の dategettest.bat にあるように、18種類の変数に各値を入れてくれるので、それを参照するだけです。呼ぶ側で他の変数を使う場合は、この18種類の変数名と被らないようにコーディングしてください。
この汎用バッチの中身について勉強したくなるのは、翌日が欲しいとか、前日が欲しいとか言う場面が出てきたときではないかなと思います。そうときはこのソースをじっくり読んでいただいて改造するといいかもしれません。
困っている時に「本当に欲しいもの」をいただけた思いです。
コピペまで許容いただき本当に助かりました。
ありがとうございます!