Last active
December 11, 2015 21:58
-
-
Save davidruhmann/4666270 to your computer and use it in GitHub Desktop.
[Batch] Gregorian Calendar
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
:: Gregorian Calendar | |
:: by David Ruhmann | |
:: NOTES: | |
:: Requires date format %Date%="ddd MM/dd/yyyy" to default today's date. | |
:: This is only a proof of concept that may still have some bugs. | |
@echo off | |
:: Example Call | |
set "Year=2012" | |
set "Month=005" | |
set "Day=10" | |
call :DaysAgo 6542 | |
echo %Year% %Month% %Day% | |
set "Year=2013" | |
set "Month=04" | |
set "Day=09" | |
call :DaysAhead 6542 | |
echo %Year% %Month% %Day% | |
goto End | |
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: | |
:DaysAhead <Days> | |
setlocal EnableExtensions | |
set "Days=%~1" | |
if not defined Days ( exit /b 1 ) | |
:: Today | |
if not defined Year set "Year=%Date:~10,4%" | |
if not defined Month set "Month=%Date:~4,2%" | |
if not defined Day set "Day=%Date:~7,2%" | |
:: Validate | |
if %Year% lss 10 set "Year=%Year:~-1%" | |
if %Year% lss 100 set "Year=%Year:~-2%" | |
if %Year% lss 1000 set "Year=%Year:~-3%" | |
if %Month% lss 10 set "Month=%Month:~-1%" | |
if %Day% lss 10 set "Day=%Day:~-1%" | |
::if %Days% lss 1 ( echo Invalid Input ) | |
:: Generate Calendar | |
call :Calendar %Year% || ( exit /b 2 ) | |
set /a "Days+=Day" | |
set /a "Day=Month[%Month%]" | |
:LoopAhead | |
if %Days% lss %Day% ( goto StopAhead ) | |
:: Subtract Day Count | |
set /a "Days-=Day" | |
:: Previous Month | |
set /a "Month+=1" | |
if defined Month[%Month%] ( | |
set /a "Day=Month[%Month%]" | |
goto LoopAhead | |
) | |
:: Next Year | |
set /a "Year+=1" | |
call :IsLeap %Year% && set "Month[2]=28" || set "Month[2]=29" | |
:: Reset Month | |
set /a "Month=1" | |
if defined Month[%Month%] ( | |
set /a "Day=Month[%Month%]" | |
goto LoopAhead | |
) | |
:StopAhead | |
set /a "Day=Days" | |
endlocal & ( | |
set /a "Month=%Month%" | |
set /a "Day=%Day%" | |
set /a "Year=%Year%" | |
) | |
exit /b 0 | |
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: | |
:DaysAgo <Days> | |
setlocal EnableExtensions | |
set "Days=%~1" | |
if not defined Days ( exit /b 1 ) | |
:: Today | |
if not defined Day set "Day=%Date:~7,2%" | |
if not defined Year set "Year=%Date:~10,4%" | |
if not defined Month set "Month=%Date:~4,2%" | |
:: Validate | |
if %Year% lss 10 set "Year=%Year:~-1%" | |
if %Year% lss 100 set "Year=%Year:~-2%" | |
if %Year% lss 1000 set "Year=%Year:~-3%" | |
if %Month% lss 10 set "Month=%Month:~-1%" | |
if %Day% lss 10 set "Day=%Day:~-1%" | |
:: Generate Calendar | |
call :Calendar %Year% || ( exit /b 2 ) | |
:LoopAgo | |
:: Subtract Day | |
set /a "Days-=Day" | |
if %Days% lss 1 ( goto StopAgo ) | |
:: Previous Month | |
set /a "Month-=1" | |
if defined Month[%Month%] ( | |
set /a "Day=Month[%Month%]" | |
goto LoopAgo | |
) | |
:: Previous Year | |
set /a "Year-=1" | |
call :IsLeap %Year% && set "Month[2]=28" || set "Month[2]=29" | |
:: Reset Month | |
set /a "Month=12" | |
if defined Month[%Month%] ( | |
set /a "Day=Month[%Month%]" | |
goto LoopAgo | |
) | |
:StopAgo | |
set /a "Day=-Days" | |
endlocal & ( | |
set /a "Month=%Month%" | |
set /a "Day=%Day%" | |
set /a "Year=%Year%" | |
) | |
exit /b 0 | |
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: | |
:Calendar [Year] | |
:: Gregorian Calendar [Also Julian up to year 2800] | |
setlocal EnableExtensions | |
set "Year=%~1" | |
if not defined Year ( set "Year=%Date:~10,4%" ) | |
call :IsYear %Year% || ( exit /b 1 ) | |
endlocal & ( call :February %Year% ) | |
set "Month[1]=31" | |
set "Month[3]=31" | |
set "Month[4]=30" | |
set "Month[5]=31" | |
set "Month[6]=30" | |
set "Month[7]=31" | |
set "Month[8]=31" | |
set "Month[9]=30" | |
set "Month[10]=31" | |
set "Month[11]=30" | |
set "Month[12]=31" | |
exit /b 0 | |
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: | |
:February <Year> | |
call :IsLeap %~1 && set "Month[2]=28" || set "Month[2]=29" | |
exit /b 0 | |
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: | |
:IsLeap <Year> | |
:: A Leap Year is divisible by 400 or divisible by 4 and not divisible by 100. | |
setlocal EnableExtensions | |
::call :IsYear %~1 || ( exit /b 0 ) | |
set /a "Leap=%~1 %% 400" | |
if "%Leap%" == "0" ( endlocal & exit /b 1 ) else ( set /a "Leap=%~1 %% 100" ) | |
if "%Leap%" == "0" ( endlocal & exit /b 0 ) else ( set /a "Leap=%~1 %% 4" ) | |
if "%Leap%" == "0" ( endlocal & exit /b 1 ) | |
endlocal & exit /b 0 | |
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: | |
:IsYear <Year> | |
:: Only support Anno Domini upto 4000. By then leap formula might need revision. | |
:: 2800 is the first year where the Julian and Gregorian calendars disagree. | |
:: 4000 is the first leap year where the Gregorian calendar might be wrong. | |
setlocal EnableExtensions | |
set "Year=%~1" | |
if not defined Year ( exit /b 1 ) | |
if %Year% lss 1 ( echo Invalid Year: %Year% & exit /b 2 ) | |
if %Year% gtr 3999 ( echo Invalid Year: %Year% & exit /b 3 ) | |
endlocal & exit /b 0 | |
:End | |
endlocal | |
pause >nul |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Verify with http://www.timeanddate.com/date/dateadd.html