" Compute the Gregorian date of Easter in a given year as a Dictionary " Butcher-Meeus algorithm (cf. Wikipedia) " https://en.wikipedia.org/wiki/Computus#Anonymous_Gregorian_algorithm " https://fr.wikipedia.org/wiki/Calcul_de_la_date_de_P%C3%A2ques#M%C3%A9thode_moderne_de_calcul_de_la_date_de_P%C3%A2ques " Maintainer: Tony Mechelynck " Version: 1.0 " Date: 2 May 2020 " Invocation: " let dic = easter#date(year) " if !empty(dic) | echo dic.year . '-' . dic.month . '-' . dic.day 'is an Easter sunday' | endif " argument is Gregorian year i.e. 1583 or greater " - A String or (the integer part of) a Float are converted to integer " the usual Vim way " - Non-numeric types, or values < 1583, cause an error and return {} " - Otherwise, the returned dictionary has the following self-explanatory " keys: " year: the given year, as converted to integer if necessary " month: the month (3 or 4) " day: the day (1 to 31). Dates from 22 March to 25 April are possible. " To install, drop in autoload/ subdirectory " of any directory in 'runtimepath' function easter#date(y) " check argument and convert if necessary if type(a:y) == type(0) " integer let l:y = a:y " use as-is elseif type(a:y) == type('0') " string let l:y = a:y + 0 " convert string to integer elseif type(a:y) == type (0.0) " float let l:y = float2nr(a:y) " convert integer part to integer else " otherwise it's an error echoerr "Easter year must be integer:" a:y return {} endif if (l:y < 1583) if type(a:y) == type(l:y) echoerr "Non-gregorian year:" a:y else echoerr "Non-gregorian year:" l:y '(from' a:y . ')' endif return {} endif " Now we know that l:y is an integer > 1582 let n = l:y % 19 " Meton's cycle let c = l:y / 100 " century let u = l:y % 100 " year within century let s = c / 4 " cycle of 400 years let t = c % 4 " century mod 4 let p = (c + 8) / 25 " proemptosis cycle let q = (c - p + 1) / 3 " proemptosis value let e = ((n * 19) + c - s - q + 15) % 30 " epact let b = u / 4 " leap year cycle let d = u % 4 " leap year let l7 = (((t + b) * 2) - e - d + 32) % 7 " dominical letter let h = (n + (11 * (e + (2 * l7)))) / 451 " correction, back 1 week let rv = (e + l7 + 114 - (7 * h)) " temporary result return {'year':(l:y), 'month': (rv / 31), 'day':(1 + (rv % 31))} endfunc