[How-To] Calculate the date of Easter Sunday, for both the Gregorian and the Julian (Orthodox) Calendar

Discussion forum for all Windows batch related topics.

Moderator: DosItHelp

Post Reply
Message
Author
aGerman
Expert
Posts: 4678
Joined: 22 Jan 2010 18:01
Location: Germany

[How-To] Calculate the date of Easter Sunday, for both the Gregorian and the Julian (Orthodox) Calendar

#1 Post by aGerman » 29 Sep 2020 11:18

Because of a recent request I searched the forum for an Easter calculation but didn't find one. Here you go ...

Gregorian Calendar

Code: Select all

@echo off &setlocal EnableDelayedExpansion

for %%i in (1590 1666 1685 1924 1943 1962 2019 2038 2057 2076 2095 2133 2152 2171 2190) do (
  call :easter %%i
  echo !errorlevel!
)
echo ~~~~~~~~~~~~~~~
for %%i in (1876 1974 2045 2069 2089 2096) do (
  call :easter %%i
  echo !errorlevel!
)
echo ~~~~~~~~~~~~~~~
for %%i in (1802 1805 1818 1825 1829 1845 1900 1903 1923 1927 1954 1967 1981 2049 2076 2106 2119 2133 2147 2150 2170 2174) do (
  call :easter %%i
  echo !errorlevel!
)
pause
goto :eof


:easter
setlocal
set /a "y=%~1,a=y%%19,b=y/100,c=y%%100,h=(19*a+b-b/4-(b-(b+8)/25+1)/3+15)%%30,l=(32+b%%4*2+c/4*2-h-c%%4)%%7,n=h+l-(a+11*h+22*l)/451*7+114,o=y*10000+n/31*100+n%%31+1"
endlocal &exit /b %o%
The Easter calculation is based on the Anonymous Easter Algorithm for the Gregorian calendar.
https://en.wikipedia.org/wiki/Computus# ... _algorithm
It's shortened by replacing some variables with their formula.
The algorithm has been verified using the years with an Easter-paradox in the code above. Those are years where the astronomically correct Easter date is other than the Easter date calculated by the agreed algorithm for the Gregorian calendar. The output has to be always the latter.
https://en.wikipedia.org/wiki/Computus# ... ster_dates
https://de.wikipedia.org/wiki/Osterparadoxon (German site because I didn't find an appropriate English one.)

The :easter subroutine expects a four digits year as parameter. It returns the date of Easter Sunday using format YYYYMMDD, accessible in the errorlevel variable. The format meets the order of the first 8 digits of the WMI LocalDateTime string to facilitate comparisons.

Code: Select all

@echo off &setlocal
for /f %%i in ('WMIC OS Get LocalDateTime /value') do for /f %%j in ("%%i") do set "%%j"

call :easter %LocalDateTime:~0,4%
if %errorlevel%==%LocalDateTime:~0,8% echo Happy Easter!

pause
goto :eof


:easter
setlocal
set /a "y=%~1,a=y%%19,b=y/100,c=y%%100,h=(19*a+b-b/4-(b-(b+8)/25+1)/3+15)%%30,l=(32+b%%4*2+c/4*2-h-c%%4)%%7,n=h+l-(a+11*h+22*l)/451*7+114,o=y*10000+n/31*100+n%%31+1"
endlocal &exit /b %o%

Julian Calendar

In a couple of counties the calculation is based on the Julian Calendar, e.g. the Russian-Orthodox Easter (Пасха). This is both easier and more difficult at the same time. The actual calculation is shorter. I used Meeus's Julian algorithm.
https://en.wikipedia.org/wiki/Computus# ... _algorithm
The result is Easter in the Julian calendar. This is likely not quite helpful though. Even if the Julian calendar is used to determine the date, the official calendar in those countries will be probably the Gregorian calendar. Thus, it might be required to convert from the Julian to the Gregorian calendar date afterwards.

Code: Select all

@echo off &setlocal
for /f %%i in ('WMIC OS Get LocalDateTime /value') do for /f %%j in ("%%i") do set "%%j"

call :easter_jul %LocalDateTime:~0,4%
echo Jul.:  %errorlevel%
call :jul2greg %errorlevel%
echo Greg.: %errorlevel%

pause
goto :eof


:easter_jul
setlocal
set /a "y=%~1,d=(y%%19*19+15)%%30,f=d+(y%%4*2+y%%7*4-d+34)%%7+114,g=y*10000+f/31*100+f%%31+1"
endlocal &exit /b %g%

:jul2greg
setlocal
set "s=%~1"
set /a "y=%s:~0,4%,m=100%s:~4,2%%%100,d=100%s:~6,2%%%100,a=(14-m)/12,h=(y-a)/100,b=y+4800-a,c=(153*(m+12*a-3)+2)/5+d+b*365+b/4-b/100+b/400+h/4*3+h%%4-3,d=(4*c+3)/146097,e=-d*146097/4+c,f=(4*e+3)/1461,g=(-1461*f)/4+e,h=(5*g+2)/153,i=10000*(d*100+f-4800+h/10)+100*((-h/10)*12+h+3)+((153*h+2)/-5)+g+1"
endlocal &exit /b %i%
Parameter format for :easter_jul is YYYY, the returned value has format YYYYMMDD.
For :jul2greg both the input parameter and the return value have format YYYYMMDD.

Of course both the Julian Easter calculation and the conversion into a Gregorian date can also be done in one step :wink:

Code: Select all

@echo off &setlocal EnableDelayedExpansion
for %%i in (2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024) do (
  call :easter_jul_in_greg %%i
  echo !errorlevel!
)

pause
goto :eof


:easter_jul_in_greg
setlocal
set /a "y=%~1,d=(y%%19*19+15)%%30,f=d+(y%%4*2+y%%7*4-d+34)%%7+114,m=f/31,a=(14-m)/12,h=(y-a)/100,b=y+4800-a,c=(153*(m+12*a-3)+2)/5+f%%31+b*365+b/4-b/100+b/400+h/4*3+h%%4-2,d=(4*c+3)/146097,e=-d*146097/4+c,f=(4*e+3)/1461,g=(-1461*f)/4+e,h=(5*g+2)/153,i=10000*(d*100+f-4800+h/10)+100*((-h/10)*12+h+3)+((153*h+2)/-5)+g+1"
endlocal &exit /b %i%
Steffen

Aacini
Expert
Posts: 1914
Joined: 06 Dec 2011 22:15
Location: México City, México
Contact:

Re: [How-To] Calculate the date of Easter Sunday, for both the Gregorian and the Julian (Orthodox) Calendar

#2 Post by Aacini » 05 Oct 2020 04:41

At the end of this post I posted some time ago this subroutine that calculate the Easter Sunday based on integer arithmetic:

Code: Select all

:EasterSunday year
rem Calculate the date of Christian Easter Sunday of any given year
rem Antonio Perez Ayala
set /A A=%1%%19, B=%1/100, C=%1%%100, D=B/4, E=B%%4, F=(B+8)/25, G=(B-F+1)/3, H=(A*19+B-D-G+15)%%30, I=C/4
set /A K=C%%4, L=((E+I)*2-H-K+32)%%7, M=(A+H*11+L*22)/451, N=H+L-M*7+114, Month=N/31, Day=N%%31+1
echo %Month%/%Day%/%1
This method first appeared in "Butcher's Ecclesiastical Calendar" on 1876, but was reprinted on 1981 in "Practical Astronomy with your Calculator, 2nd Edition", Peter Duffett-Smith, Cambridge University Press.

Antonio

aGerman
Expert
Posts: 4678
Joined: 22 Jan 2010 18:01
Location: Germany

Re: [How-To] Calculate the date of Easter Sunday, for both the Gregorian and the Julian (Orthodox) Calendar

#3 Post by aGerman » 05 Oct 2020 06:22

Obviously I didn't expect to find a Batch routine in your thread, Antonio :lol: Sorry.

Steffen

Post Reply