https://en.wikipedia.org/w/index.php?action=history&feed=atom&title=Module%3AEaster%2FsandboxModule:Easter/sandbox - Revision history2025-05-29T05:34:29ZRevision history for this page on the wikiMediaWiki 1.45.0-wmf.2https://en.wikipedia.org/w/index.php?title=Module:Easter/sandbox&diff=731398286&oldid=prevPC-XT: create synced2016-07-25T03:18:13Z<p>create synced</p>
<p><b>New page</b></p><div>local m = {}<br />
<br />
local EasterData = {<br />
defaultMethod = 3, -- default method of Easter date calculation when Easter type is not given<br />
defaultFormat = "Y-m-d", -- default date output format<br />
noFormat = "none", -- prevent from final date formatting<br />
defaultOffset = 0, -- the Easter date<br />
minimumOffset = -63, -- Septuagesima<br />
maximumOffset = 69, -- Feast of the Immaculate Heart of Mary<br />
<br />
-- API<br />
apiEaster = "Calculate", -- public function name<br />
argEasterYear = 1, -- index or name of the argument with year<br />
argEasterMethod = "method", -- index or name of the argument with calculation method<br />
argEasterOffset = "day", -- index or name of the argument with offset in days relative to the calculated Easter Sunday<br />
argEasterFormat = "format", -- index or name of the argument with date output format (#time style)<br />
<br />
-- errors<br />
errorMissingYear = "Missing mandatory argument 'year'",<br />
errorInvalidYear = "Incorrect argument 'year': '%s'",<br />
errorInvalidOffset = "Incorrect argument 'day': '%s'",<br />
errorInvalidMethod = "Incorrect argument 'method': '%s'",<br />
errorYearOutOfRange = "Easter dates are available between years 326 and 4099; year: %d",<br />
errorIncorrectMethod = "Western or Orthodox Easter exists since 1583; year: %d",<br />
errorUnknownMethod = "Unknown method: %d",<br />
<br />
methods = {<br />
["Julian"] = 1,<br />
["Eastern"] = 2,<br />
["Orthodox"] = 2, -- alias for Eastern<br />
["Coptic"] = 2, -- alias for Eastern<br />
["Ethiopian"] = 2, -- alias for Eastern<br />
["Western"] = 3,<br />
["Gregorian"] = 3, -- alias for Western<br />
["Roman"] = 3, -- alias for Western<br />
},<br />
-- the Meletian/Revised Julian Calendar from 1923 used by some Orthodox churches<br />
-- and any proposed reformed algorithms are not supported (yet):<br />
-- * astronomically observed Nicean rule at the meridian of Jerusalem (Aleppo 1997 proposal), differs from Gregorian in <br />
-- * fifteenth Sunday of the year: Sunday in 099–105 day of the year<br />
-- * Sunday after second Saturday in April (UK): Sunday in 9–15 April<br />
-- * second Sunday in April: Sunday in 8–14 April<br />
-- * Sunday after 6 April (Pepuzite sect): Sunday in 7–13 April<br />
-- * World Calendar: day 099, any day of the week in Gregorian/Julian calendar<br />
-- * Positivist Calendar: day 098, any day of the week in Gregorian/Julian calendar<br />
<br />
-- * Sunday of ISO week 14: Sunday in 099–105 day of the year<br />
<br />
-- * Sunday of ISO week 15: Sunday in 106–112 day of the year<br />
-- * Nisan 14: any day of the week<br />
<br />
-- * Nisan 15: any day of the week<br />
<br />
<br />
relativeDates = {<br />
["Septuagesima"] = -63,<br />
["Sexagesima"] = -56,<br />
["Fat Thursday"] = -52,<br />
["Quinquagesima"] = -49, -- Estomihi, Shrove Sunday<br />
["Shrove Monday"] = -48, -- Rose Monday<br />
["Shrove Tuesday"] = -47, -- Mardi Gras, Carnival<br />
["Ash Wednesday"] = -46,<br />
["Laetare Sunday"] = -21,<br />
["Palm Sunday"] = -7,<br />
["Holy Wednesday"] = -4, <br />
["Maundy Thursday"] = -3,<br />
["Good Friday"] = -2, -- Crucifixion<br />
["Holy Saturday"] = -1, <br />
["Easter"] = 0, -- Easter Sunday, Resurrection<br />
["Easter Monday"] = 1,<br />
["Divine Mercy"] = 7,<br />
["Ascension Thursday"] = 39, -- Ascension<br />
["Pentecost"] = 49, -- Whitsun<br />
["Trinity Sunday"] = 56, <br />
["Corpus Christi"] = 60, -- Body and Blood of Christ<br />
["Sacred Heart"] = 68,<br />
["Immaculate Heart"] = 69,<br />
},<br />
}<br />
<br />
local function formatEasterError(message, ...)<br />
if select('#', ... ) > 0 then<br />
message = string.format(message, ...)<br />
end<br />
return "<span class=\"error\">" .. message .. "</span>"<br />
end<br />
<br />
local function loadEasterYear(year)<br />
if not year then<br />
return false, formatEasterError(EasterData.errorMissingYear)<br />
end<br />
local result = tonumber(year)<br />
if not result or math.floor(result) ~= result then<br />
return false, formatEasterError(EasterData.errorInvalidYear, year)<br />
end<br />
<br />
return true, result<br />
end<br />
<br />
local function loadEasterMethod(method, year)<br />
local result = EasterData.defaultMethod<br />
if method then<br />
result = EasterData.methods[method]<br />
if not result then<br />
return false, formatEasterError(EasterData.errorInvalidMethod, method)<br />
end<br />
end<br />
<br />
if year < 1583 then<br />
result = 1<br />
end<br />
<br />
return true, result<br />
end<br />
<br />
local function loadEasterOffset(day)<br />
if not day then<br />
return true, ""<br />
end<br />
<br />
local data = EasterData.relativeDates<br />
local offset = tonumber(day)<br />
if not offset then<br />
offset = data[day]<br />
end<br />
if not offset or offset ~= math.floor(offset) or offset < EasterData.minimumOffset or offset > EasterData.maximumOffset then<br />
return false, formatEasterError(EasterData.errorInvalidOffset, day)<br />
end<br />
<br />
if offset < -1 then<br />
return true, string.format(" %d days", offset)<br />
elseif offset == -1 then<br />
return true, " -1 day"<br />
elseif offset == 0 then<br />
return true, ""<br />
elseif offset == 1 then<br />
return true, " +1 day"<br />
else -- if offset > 1 then<br />
return true, string.format(" +%d days", offset)<br />
end<br />
end<br />
<br />
local function loadEasterFormat(fmt)<br />
if fmt == EasterData.noFormat then<br />
return true, nil<br />
elseif not fmt then<br />
return true, EasterData.defaultFormat<br />
else<br />
return true, fmt<br />
end<br />
end<br />
<br />
--[[<br />
PURPOSE: This function returns Easter Sunday day and month<br />
for a specified year and method.<br />
<br />
INPUTS: Year - Any year between 326 and 4099.<br />
Method - 1 = the original calculation based on the<br />
Julian calendar<br />
2 = the original calculation, with the<br />
Julian date converted to the<br />
equivalent Gregorian calendar<br />
3 = the revised calculation based on the<br />
Gregorian calendar<br />
<br />
OUTPUTS: None.<br />
<br />
RETURNS: 0, error message - Error; invalid arguments<br />
month, day - month and day of the Sunday<br />
<br />
NOTES:<br />
The code is translated from DN OSP 6.4.0 sources.<br />
The roots of the code might be found in<br />
http://www.gmarts.org/index.php?go=415<br />
<br />
ORIGINAL NOTES:<br />
<br />
This algorithm is an arithmetic interpretation<br />
of the 3 step Easter Dating Method developed<br />
by Ron Mallen 1985, as a vast improvement on<br />
the method described in the Common Prayer Book<br />
<br />
Published Australian Almanac 1988<br />
Refer to this publication, or the Canberra Library<br />
for a clear understanding of the method used<br />
<br />
Because this algorithm is a direct translation of<br />
the official tables, it can be easily proved to be<br />
100% correct<br />
<br />
It's free! Please do not modify code or comments!<br />
]]<br />
local function calculateEasterDate(year, method)<br />
if year < 326 or year > 4099 then<br />
-- Easter dates are valid for years between 326 and 4099<br />
-- Method 2 would have to support dates in June thereafter<br />
return 0, formatEasterError(EasterData.errorYearOutOfRange, year)<br />
end<br />
if year < 1583 and method ~= 1 then<br />
-- Western or Orthodox Easter is valid since 1583<br />
return 0, formatEasterError(EasterData.errorIncorrectMethod, year)<br />
end<br />
<br />
-- intermediate result<br />
local firstDig = math.floor(year / 100)<br />
local remain19 = year % 19<br />
local temp = 0<br />
-- table A to E results<br />
local tA = 0<br />
local tB = 0<br />
local tC = 0<br />
local tD = 0<br />
local tE = 0<br />
-- Easter Sunday day<br />
local d = 0<br />
<br />
if method == 1 or method == 2 then<br />
-- calculate PFM date<br />
tA = ((225 - 11 * remain19) % 30) + 21<br />
-- find the next Sunday<br />
tB = (tA - 19) % 7<br />
tC = (40 - firstDig) % 7<br />
temp = year % 100<br />
tD = (temp + math.floor(temp / 4)) % 7<br />
tE = ((20 - tB - tC - tD) % 7) + 1<br />
d = tA + tE<br />
if method == 2 then<br />
-- convert Julian to Gregorian date<br />
-- 10 days were skipped in the Gregorian calendar from 5-14 Oct 1582<br />
temp = 10<br />
-- only 1 in every 4 century years are leap years in the Gregorian<br />
-- calendar (every century is a leap year in the Julian calendar)<br />
if year > 1600 then<br />
temp = temp + firstDig - 16 - math.floor((firstDig - 16) / 4)<br />
end<br />
d = d + temp<br />
end<br />
elseif method == 3 then<br />
-- calculate PFM date<br />
temp = math.floor((firstDig - 15) / 2) + 202 - 11 * remain19<br />
if firstDig > 26 then<br />
temp = temp - 1<br />
end<br />
if firstDig > 38 then<br />
temp = temp - 1<br />
end<br />
if firstDig == 21 or firstDig == 24 or firstDig == 25 or firstDig == 33 or firstDig == 36 or firstDig == 37 then<br />
temp = temp - 1<br />
end<br />
temp = temp % 30<br />
tA = temp + 21<br />
if temp == 29 then<br />
tA = tA - 1<br />
end<br />
if temp == 28 and remain19 > 10 then<br />
tA = tA - 1<br />
end<br />
-- find the next Sunday<br />
tB = (tA - 19) % 7<br />
tC = (40 - firstDig) % 4<br />
if tC == 3 then<br />
tC = tC + 1<br />
end<br />
if tC > 1 then<br />
tC = tC + 1<br />
end<br />
temp = year % 100<br />
tD = (temp + math.floor(temp / 4)) % 7<br />
tE = ((20 - tB - tC - tD) % 7) + 1<br />
d = tA + tE<br />
else<br />
-- Unknown method<br />
return 0, formatEasterError(EasterData.errorUnknownMethod, method)<br />
end<br />
if d > 61 then<br />
-- when the original calculation is converted to the Gregorian<br />
-- calendar, Easter Sunday can occur in May<br />
return 5, d - 61<br />
elseif d > 31 then<br />
return 4, d - 31<br />
else<br />
return 3, d<br />
end<br />
end<br />
<br />
local function Easter(args)<br />
local ok<br />
local year<br />
ok, year = loadEasterYear(args[EasterData.argEasterYear])<br />
if not ok then<br />
return year<br />
end<br />
<br />
local method<br />
ok, method = loadEasterMethod(args[EasterData.argEasterMethod], year)<br />
if not ok then<br />
return method<br />
end<br />
<br />
local offset<br />
ok, offset = loadEasterOffset(args[EasterData.argEasterOffset])<br />
if not ok then<br />
return offset<br />
end<br />
<br />
local format<br />
ok, format = loadEasterFormat(args[EasterData.argEasterFormat])<br />
if not ok then<br />
return format<br />
end<br />
<br />
local month, day = calculateEasterDate(year, method)<br />
if month == 0 then<br />
return day<br />
end<br />
<br />
local result = string.format("%04d-%02d-%02d%s", year, month, day, offset)<br />
if format then<br />
result = mw.language.getContentLanguage():formatDate(format, result)<br />
end<br />
<br />
return result<br />
end<br />
<br />
m[EasterData.apiEaster] = function (frame)<br />
return Easter(frame.args)<br />
end<br />
<br />
return m</div>PC-XT