- note -

Batch

7/10

日付の操作   - Last modified:2014/7/19

batで日付の操作ができると便利だなーと思っていたので、
そんな感じのものを作ってみました。
できることは、
現在日付から指定した[日|月|年]だけ[加算|減算]した日付の[表示|適用]です。
ソースは昔書いた書きかけをベースにしているのでかなり汚い感じですが、
取り敢えず動けばよしです。
batに綺麗なソースを求めても仕方ありません。
そんなこと言うくらいなら初めからPowerShellを使っています。
@echo off
setlocal enabledelayedexpansion

if "%~1" == "" exit /b

set nowDate=%date%
set year=%nowDate:~0,4%
set month=%nowDate:~5,2%
set day=%nowDate:~8,2%

if %month:~0,1% == 0 set month=%month:~1%
if %day:~0,1% == 0 set day=%day:~1%

set applyDate=0
set changeYear=0
set changeMonth=0
:parse_option
if "%~1" == "/?" (
  echo usage: %~n0 [/c] [/y^|/m] ^<+^|-^>nn
  exit /b
) else if "%~1" == "/c" (
  set applyDate=1
  shift
) else if "%~1" == "/y" (
  set changeYear=1
  shift
) else if "%~1" == "/m" (
  set changeMonth=1
  shift
) else (
  if not "%~2" == "" exit /b
)
if not "%~2" == "" goto parse_option
:parse_end

if %changeYear% == 1 if %changeMonth% == 1 exit /b

set value=%1
set sign=%value:~0,1%

if not "%sign%" == "+" if not "%sign%" == "-" exit /b

set dayCount[1]=31
set dayCount[2]=28
set dayCount[3]=31
set dayCount[4]=30
set dayCount[5]=31
set dayCount[6]=30
set dayCount[7]=31
set dayCount[8]=31
set dayCount[9]=30
set dayCount[10]=31
set dayCount[11]=30
set dayCount[12]=31

call :ApplyLeapDay %year% dayCount[2]

if %changeYear% == 0 if %changeMonth% == 0 goto day_loop
set value=%value:~1%
if %changeYear% == 1 (
  set /a year%sign%=value
) else (
  set /a month%sign%=value%%12
  set /a "wrapround=((%sign%1-1)/-2*13%sign%month)/13"
  if !wrapround! == 1 (
    set /a year%sign%=1
    set /a month-=%sign%12
  )
  set /a year%sign%=value/12
)
call :ApplyLeapDay %year% dayCount[2]
if %day% gtr !dayCount[%month%]! set day=!dayCount[%month%]!
goto finish

:day_loop
set /a check=day+value
set dayCount=!dayCount[%month%]!
if 1 leq %check% if %check% leq %dayCount% (
  set day=%check%
  goto finish
)
set /a value=check-(%sign%1+1)/2*(%sign%dayCount+1)%sign%1
set /a month%sign%=1
set /a wrapround=^^^!month+^^^!(month-13)
if %wrapround% == 1 (
  set /a month%sign%=-12
  set /a year%sign%=1
  call :ApplyLeapDay !year! dayCount[2]
)
set dayCount=!dayCount[%month%]!
set /a day=(%sign%1-1)/-2*(dayCount+1)
goto day_loop

:finish
if "%month:~1%" == "" set month=0%month%
if "%day:~1%" == "" set day=0%day%
set result=%year%/%month%/%day%
echo %result%
if %applyDate% == 1 date %result%
exit /b

:ApplyLeapDay
set /a "check=^!(%1%%400)|^!^!(%1%%100)&^!(%1%%4)"
set /a %2=28+%check%
exit /b

使用例

■今日の日付が2011/12/31の場合

3日後の日付を表示

>DateManager.bat +3
2012/01/03

2ヵ月後の日付を表示

>DateManager.bat /m +2
2012/02/29

現在の日付を4年前に設定

>date /t
2011/12/31

>DateManager.bat /c /y -4
2007/12/31

>date /t
2007/12/31