Skip to content

Instantly share code, notes, and snippets.

@davidruhmann
Last active December 11, 2015 21:58
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save davidruhmann/4666270 to your computer and use it in GitHub Desktop.
Save davidruhmann/4666270 to your computer and use it in GitHub Desktop.
[Batch] Gregorian Calendar
:: 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
@davidruhmann
Copy link
Author

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment