Module:Pasen

Uit Wiki Raamsdonks Erfgoed

Module om de paasdatum en daarvan afgeleide data te berekenen.

Bereken

Functie om de datum van Pasen of van een aan Pasen gerelateerde feestdag te berekenen.

parameters

Veld Doel Voorbeeldparameter
1 Jaar 2024 of 1882
methode Berekeningsmethode van de paasdatum:
Juliaans
oorspronkelijke berekening voor de Juliaanse kalender
Oosters of Orthodox
oorspronkelijke berekening voor de Juliaanse kalender, omgerekend naar de Gregoriaanse kalender
Westers of Rooms of Gregoriaans
herziene berekening voor de Gregoriaanse kalender. Dit is de verstekwaarde.
Oosters om de paasdatum te berekenen in de Orthodoxe ritus.
dag Naam van de aan Pasen gerelateerde feestdag, of een geheel aantal dagen voor (negatief) of na (positief) Paaszondag. De volgende dagen zijn bij naam beschikbaar:
Septuagesima
63 dagen voor Pasen – dit is de vroegste datum die de functie kan retourneren
Sexagesima
56 dagen voor Pasen
Quinquagesima of Estomihi
49 dagen voor Pasen
Vastenavond of Carnaval
47 dagen voor Pasen
Aswoensdag
46 dagen voor Pasen
Invocabit
42 dagen voor Pasen
Reminiscere
35 dagen voor Pasen
Oculi
28 dagen voor Pasen
Laetare of Halfvasten
21 dagen voor Pasen
Judica
14 dagen voor Pasen
Palmpasen
7 dagen voor Pasen
Schorselwoensdag of Schortelwoensdag
4 dagen voor Pasen
Witte Donderdag
3 dagen voor Pasen
Goede Vrijdag
2 dagen voor Pasen
Stille Zaterdag
1 dagen voor Pasen
Pasen
0 – noch voor noch na – dit is de verstekwaarde
Paasmaandag of Tweede paasdag
1 dagen na Pasen
Beloken Pasen of Quasimodo-zondag of Quasi modo geniti
7 dagen na Pasen
Misericordias Domini
14 dagen na Pasen
Jubilate
21 dagen na Pasen
Cantate
28 dagen na Pasen
Rogate
35 dagen na Pasen
Hemelvaart
39 dagen na Pasen
Exaudi of Wezenzondag
42 dagen na Pasen
Pinksteren
49 dagen na Pasen
Pinkstermaandag
50 dagen na Pasen
Trinitatis
56 dagen na Pasen
Sacramentsdag
60 dagen na Pasen
Sacramentszondag
63 dagen na Pasen
1e zondag na Trinitatis
63 dagen na Pasen
Heilig Hart
68 dagen na Pasen
Onbevlekt Hart van Maria
69 dagen na Pasen
2e zondag na Trinitatis
70 dagen na Pasen
3e zondag na Trinitatis
77 dagen na Pasen
4e zondag na Trinitatis
84 dagen na Pasen
5e zondag na Trinitatis
91 dagen na Pasen
6e zondag na Trinitatis
98 dagen na Pasen
7e zondag na Trinitatis
105 dagen na Pasen
8e zondag na Trinitatis
112 dagen na Pasen
9e zondag na Trinitatis
119 dagen na Pasen
10e zondag na Trinitatis
126 dagen na Pasen
11e zondag na Trinitatis
133 dagen na Pasen
12e zondag na Trinitatis
140 dagen na Pasen
13e zondag na Trinitatis
147 dagen na Pasen
14e zondag na Trinitatis
154 dagen na Pasen
15e zondag na Trinitatis
161 dagen na Pasen
16e zondag na Trinitatis
168 dagen na Pasen
17e zondag na Trinitatis
175 dagen na Pasen
18e zondag na Trinitatis
182 dagen na Pasen
19e zondag na Trinitatis
189 dagen na Pasen
20e zondag na Trinitatis
196 dagen na Pasen
21e zondag na Trinitatis
203 dagen na Pasen
22e zondag na Trinitatis
210 dagen na Pasen
23e zondag na Trinitatis
217 dagen na Pasen
24e zondag na Trinitatis
224 dagen na Pasen – bestaat niet in elk kerkelijk jaar
25e zondag na Trinitatis
231 dagen na Pasen – bestaat niet in elk kerkelijk jaar
26e zondag na Trinitatis
238 dagen na Pasen – bestaat niet in elk kerkelijk jaar
27e zondag na Trinitatis
245 dagen na Pasen – bestaat niet in elk kerkelijk jaar
28e zondag na Trinitatis
252 dagen na Pasen – bestaat niet in elk kerkelijk jaar – dit is de laatste datum die de functie kan retourneren
49 of met hetzelfde resultaat: Pinksteren
formaat Beschrijft het datumformaat voor de uitvoer, op dezelfde manier als voor de #time-parseerfunctie. Verstekformaat is Y-m-d. Er is een speciale waarde geen die formattering uitschakelt. j xd

voorbeelden

{{#invoke:Pasen|Bereken|{{CURRENTYEAR}}}}
2024-03-31
{{#invoke:Pasen|Bereken|{{CURRENTYEAR}}|methode=Oosters}}
2024-05-05
{{#invoke:Pasen|Bereken|{{CURRENTYEAR}}|formaat=[[j xg]]}}
31 maart
{{#invoke:Pasen|Bereken|{{CURRENTYEAR}}|methode=Oosters|formaat=[[j xg]]}}
5 mei
{{#invoke:Pasen|Bereken|{{CURRENTYEAR}}|dag=Aswoensdag}}
2024-02-14
{{#invoke:Pasen|Bereken|{{CURRENTYEAR}}|methode=Oosters|dag=Aswoensdag}}
2024-03-20
{{#invoke:Pasen|Bereken|{{CURRENTYEAR}}|formaat=[[j xg]] (l)|dag=Aswoensdag}}
14 februari (woensdag)
{{#invoke:Pasen|Bereken|{{CURRENTYEAR}}|methode=Oosters|formaat=[[j xg]] (l)|dag=Aswoensdag}}
20 maart (woensdag)

local m = {}

local EasterData = {
    defaultMethod = 3,        -- default method of Easter date calculation when Easter type is not given
    defaultFormat = "Y-m-d",  -- default date output format
    noFormat      = "geen",   -- prevent from final date formatting
    defaultOffset = 0,        -- the Easter date
    minimumOffset = -63,      -- Septuagesima
    maximumOffset = 252,      -- 27e zondag na Trinitatis

    -- API
    apiEaster            = "Bereken",   -- public function name
    argEasterYear        = 1,           -- index or name of the argument with year
    argEasterMethod      = "methode",   -- index or name of the argument with calculation method
    argEasterOffset      = "dag",       -- index or name of the argument with offset in days relative to the calculated Easter Sunday
    argEasterFormat      = "formaat",   -- index or name of the argument with date output format (#time style)

    -- errors
    errorMissingYear     = "Ontbrekende verplichte parameter 1 (jaar)",
    errorInvalidYear     = "Incorrecte parameter 1 (jaar): '%s'",
    errorInvalidOffset   = "Incorrecte parameter 'dag': '%s'",
    errorInvalidMethod   = "Incorrecte parameter 'methode': '%s'",
    errorYearOutOfRange  = "Paasdata zijn beschikbaar tussen de jaren 326 en 4099; jaar: %d",
    errorIncorrectMethod = "Westers of Orthodox Pasen bestaan sinds 1583; jaar: %d",
    errorUnknownMethod   = "Onbekende methode: %d",

    methods = {
        ["Juliaans"]    = 1,
        ["Oosters"]     = 2,
        ["Orthodox"]    = 2, -- alias voor Oosters
        ["Koptisch"]    = 2, -- alias voor Oosters
        ["Ethiopisch"]  = 2, -- alias voor Oosters
        ["Westers"]     = 3,
        ["Gregoriaans"] = 3, -- alias voor Westers
        ["Rooms"]       = 3, -- alias voor Westers
    },
    -- the Meletian/Revised Julian Calendar from 1923 used by some Orthodox churches
    -- and any proposed reformed algorithms are not supported (yet):
    -- * astronomically observed Nicean rule at the meridian of Jerusalem (Aleppo 1997 proposal), differs from Gregorian in 
    -- * fifteenth Sunday of the year: Sunday in 099–105 day of the year
    -- * Sunday after second Saturday in April (UK): Sunday in 9–15 April
    -- * second Sunday in April: Sunday in 8–14 April
    -- * Sunday after 6 April (Pepuzite sect): Sunday in 7–13 April
    -- * World Calendar: day 099, any day of the week in Gregorian/Julian calendar
    -- * Positivist Calendar: day 098, any day of the week in Gregorian/Julian calendar

    -- * Sunday of ISO week 14: Sunday in 099–105 day of the year

    -- * Sunday of ISO week 15: Sunday in 106–112 day of the year
    -- * Nisan 14: any day of the week

    -- * Nisan 15: any day of the week


    relativeDates = {
        ["Septuagesima"]             = -63,
        ["Sexagesima"]               = -56,
        ["Quinquagesima"]            = -49,
        ["Estomihi"]                 = -49,
        ["Vastenavond"]              = -47,
        ["Carnaval"]                 = -47,
        ["Aswoensdag"]               = -46,
        ["Invocabit"]                = -42,
        ["Reminiscere"]              = -35,
        ["Oculi"]                    = -28,
        ["Laetare"]                  = -21,
        ["Halfvasten"]               = -21,
        ["Judica"]                   = -14,
        ["Palmpasen"]                =  -7,
        ["Schorselwoensdag"]         =  -4, 
        ["Schortelwoensdag"]         =  -4, 
        ["Witte Donderdag"]          =  -3,
        ["Goede Vrijdag"]            =  -2,
        ["Stille Zaterdag"]          =  -1, 
        ["Pasen"]                    =   0,
        ["Paasmaandag"]              =   1,
        ["Tweede paasdag"]           =   1,
        ["Beloken Pasen"]            =   7,
        ["Quasimodo-zondag"]         =   7,
        ["Quasi modo geniti"]        =   7,
        ["Misericordias Domini"]     =  14,
        ["Jubilate"]                 =  21,
        ["Cantate"]                  =  28,
        ["Rogate"]                   =  35,
        ["Hemelvaart"]               =  39,
        ["Exaudi"]                   =  42,
        ["Wezenzondag"]              =  42,
        ["Pinksteren"]               =  49,
        ["Pinkstermaandag"]          =  50,
        ["Trinitatis"]               =  56, 
        ["Sacramentsdag"]            =  60,
        ["Sacramentszondag"]         =  63,
        ["1e zondag na Trinitatis"]  =  63,
        ["Heilig Hart"]              =  68,
        ["Onbevlekt Hart van Maria"] =  69,
        ["2e zondag na Trinitatis"]  =  70,
        ["3e zondag na Trinitatis"]  =  77,
        ["4e zondag na Trinitatis"]  =  84,
        ["5e zondag na Trinitatis"]  =  91,
        ["6e zondag na Trinitatis"]  =  98,
        ["7e zondag na Trinitatis"]  = 105,
        ["8e zondag na Trinitatis"]  = 112,
        ["9e zondag na Trinitatis"]  = 119,
        ["10e zondag na Trinitatis"] = 126,
        ["11e zondag na Trinitatis"] = 133,
        ["12e zondag na Trinitatis"] = 140,
        ["13e zondag na Trinitatis"] = 147,
        ["14e zondag na Trinitatis"] = 154,
        ["15e zondag na Trinitatis"] = 161,
        ["16e zondag na Trinitatis"] = 168,
        ["17e zondag na Trinitatis"] = 175,
        ["18e zondag na Trinitatis"] = 182,
        ["19e zondag na Trinitatis"] = 189,
        ["20e zondag na Trinitatis"] = 196,
        ["21e zondag na Trinitatis"] = 203,
        ["22e zondag na Trinitatis"] = 210,
        ["23e zondag na Trinitatis"] = 217,
        ["24e zondag na Trinitatis"] = 224, -- bestaat niet in elk kerkelijk jaar
        ["25e zondag na Trinitatis"] = 231, -- bestaat niet in elk kerkelijk jaar
        ["26e zondag na Trinitatis"] = 238, -- bestaat niet in elk kerkelijk jaar
        ["27e zondag na Trinitatis"] = 245, -- bestaat niet in elk kerkelijk jaar
        ["28e zondag na Trinitatis"] = 252, -- bestaat niet in elk kerkelijk jaar
    },
}

local function formatEasterError(message, ...)
    if select('#', ... ) > 0 then
        message = string.format(message, ...)
    end
    return "<span class=\"error\">" .. message .. "</span>"
end

local function loadEasterYear(year)
    if not year then
        return false, formatEasterError(EasterData.errorMissingYear)
    end
    local result = tonumber(year)
    if not result or math.floor(result) ~= result then
        return false, formatEasterError(EasterData.errorInvalidYear, year)
    end

    return true, result
end

local function loadEasterMethod(method, year)
    local result = EasterData.defaultMethod
    if method then
        result = EasterData.methods[method]
        if not result then
            return false, formatEasterError(EasterData.errorInvalidMethod, method)
        end
    end

    if year < 1583 then
        result = 1
    end

    return true, result
end

local function loadEasterOffset(day)
    if not day then
        return true, ""
    end

    local data = EasterData.relativeDates
    local offset = tonumber(day)
    if not offset then
        offset = data[day]
    end
    if not offset or offset ~= math.floor(offset) or offset < EasterData.minimumOffset or offset > EasterData.maximumOffset then
        return false, formatEasterError(EasterData.errorInvalidOffset, day)
    end

    if offset < -1 then
        return true, string.format(" %d days", offset)
    elseif offset == -1 then
        return true, " -1 day"
    elseif offset == 0 then
        return true, ""
    elseif offset == 1 then
        return true, " +1 day"
    else -- if offset > 1 then
        return true, string.format(" +%d days", offset)
    end
end

local function loadEasterFormat(fmt)
    if fmt == EasterData.noFormat then
        return true, nil
    elseif not fmt then
        return true, EasterData.defaultFormat
    else
        return true, fmt
    end
end

--[[
 PURPOSE:     This function returns Easter Sunday day and month
              for a specified year and method.

 INPUTS:      Year   - Any year between 326 and 4099.
              Method - 1 = the original calculation based on the
                           Julian calendar
                       2 = the original calculation, with the
                           Julian date converted to the
                           equivalent Gregorian calendar
                       3 = the revised calculation based on the
                           Gregorian calendar

 OUTPUTS:     None.

 RETURNS:     0, error message - Error; invalid arguments
              month, day       - month and day of the Sunday

 NOTES:
              The code is translated from DN OSP 6.4.0 sources.
              The roots of the code might be found in
              http://www.gmarts.org/index.php?go=415

 ORIGINAL NOTES:

              This algorithm is an arithmetic interpretation
              of the 3 step Easter Dating Method developed
              by Ron Mallen 1985, as a vast improvement on
              the method described in the Common Prayer Book

              Published Australian Almanac 1988
              Refer to this publication, or the Canberra Library
              for a clear understanding of the method used

              Because this algorithm is a direct translation of
              the official tables, it can be easily proved to be
              100% correct

              It's free! Please do not modify code or comments!
]]
local function calculateEasterDate(year, method)
    if year < 326 or year > 4099 then
        -- Easter dates are valid for years between 326 and 4099
        -- Method 2 would have to support dates in June thereafter
        return 0, formatEasterError(EasterData.errorYearOutOfRange, year)
    end
    if year < 1583 and method ~= 1 then
        -- Western or Orthodox Easter is valid since 1583
        return 0, formatEasterError(EasterData.errorIncorrectMethod, year)
    end

    -- intermediate result
    local firstDig = math.floor(year / 100)
    local remain19 = year % 19
    local temp = 0
    -- table A to E results
    local tA = 0
    local tB = 0
    local tC = 0
    local tD = 0
    local tE = 0
     -- Easter Sunday day
    local d = 0

    if method == 1 or method == 2 then
        -- calculate PFM date
        tA   = ((225 - 11 * remain19) % 30) + 21
        -- find the next Sunday
        tB   = (tA - 19) % 7
        tC   = (40 - firstDig) % 7
        temp = year % 100
        tD   = (temp + math.floor(temp / 4)) % 7
        tE   = ((20 - tB - tC - tD) % 7) + 1
        d    = tA + tE
        if method == 2 then
            -- convert Julian to Gregorian date
            -- 10 days were skipped in the Gregorian calendar from 5-14 Oct 1582
            temp = 10
            -- only 1 in every 4 century years are leap years in the Gregorian
            -- calendar (every century is a leap year in the Julian calendar)
            if year > 1600 then
                temp = temp + firstDig - 16 - math.floor((firstDig - 16) / 4)
            end
            d = d + temp
        end
    elseif method == 3 then
        -- calculate PFM date
        temp = math.floor((firstDig - 15) / 2)  + 202 - 11 * remain19
        if firstDig > 26 then
            temp = temp - 1
        end
        if firstDig > 38 then
            temp = temp - 1
        end
        if firstDig == 21 or firstDig == 24 or firstDig == 25 or firstDig == 33 or firstDig == 36 or firstDig == 37 then
            temp = temp - 1
        end
        temp = temp % 30
        tA   = temp + 21
        if temp == 29 then
            tA = tA - 1
        end
        if temp == 28 and remain19 > 10 then
            tA = tA - 1
        end
        -- find the next Sunday
        tB   = (tA - 19) % 7
        tC   = (40 - firstDig) % 4
        if tC == 3 then
            tC = tC + 1
        end
        if tC > 1 then
            tC = tC + 1
        end
        temp = year % 100
        tD   = (temp + math.floor(temp / 4)) % 7
        tE   = ((20 - tB - tC - tD) % 7) + 1
        d    = tA + tE
    else
        -- Unknown method
        return 0, formatEasterError(EasterData.errorUnknownMethod, method)
    end
    if d > 61 then
        -- when the original calculation is converted to the Gregorian
        -- calendar, Easter Sunday can occur in May
        return 5, d - 61
    elseif d > 31 then
        return 4, d - 31
    else
        return 3, d
    end
end

local function Easter(args)
    local ok
    local year
    ok, year = loadEasterYear(args[EasterData.argEasterYear])
    if not ok then
        return year
    end

    local method
    ok, method = loadEasterMethod(args[EasterData.argEasterMethod], year)
    if not ok then
        return method
    end

    local offset
    ok, offset = loadEasterOffset(args[EasterData.argEasterOffset])
    if not ok then
        return offset
    end

    local format
    ok, format = loadEasterFormat(args[EasterData.argEasterFormat])
    if not ok then
        return format
    end

    local month, day = calculateEasterDate(year, method)
    if month == 0 then
        return day
    end

    local result = string.format("%04d-%02d-%02d%s", year, month, day, offset)
    if format then
        result = mw.language.getContentLanguage():formatDate(format, result)
    end

    return result
end

m[EasterData.apiEaster] = function (frame)
    return Easter(frame.args)
end

return m