バッチで今月末/前月末/翌月末などを取得する

どこでも使う日付取得を汎用バッチ化する

日付を取得して、その前月とか翌月とかが欲しいときありあすよね。会社で会計処理するようなときには、前月末締めで前月末って具体的に何月何日? なんてことです。



どこでも欲しくなるような機能ですよね。それなら、汎用バッチ化して、それを呼べばすっきりするし、共通化もできます。

汎用バッチと言っているのは、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日が設定されます。


200×200 高速大容量レンタルサーバ10G
mixhost

汎用バッチ  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種類の変数名と被らないようにコーディングしてください。

この汎用バッチの中身について勉強したくなるのは、翌日が欲しいとか、前日が欲しいとか言う場面が出てきたときではないかなと思います。そうときはこのソースをじっくり読んでいただいて改造するといいかもしれません。