--Calculates the Gregorian date of a recurring holiday that varies year-to-year, but follows the rule "Nth [day of week] of [month]"
"month" = month number (1 to 12) "weeknumber" = number of week (1 to 4, or -1 to mean "last") "dayofweek" = number that represents the day of the week, where 1 = Sunday and 7 = Saturday "year" = Gregorian calendar year
require('strict')
local p =
function p.calculate(frame) local args = frame.args
local ONE_DAY = 86400 -- number of seconds in one day local year = tonumber(args.year) local month = tonumber(args.month) local weeknumber = tonumber(args.weeknumber) local dayofweek = tonumber(args.dayofweek)
local date = os.time local dateparts = os.date("*t", date) if weeknumber > 0 then -- find the first [dayofweek] of this month while dateparts["wday"] ~= dayofweek do date = date + ONE_DAY dateparts = os.date("*t", date) end
-- add the correct number of weeks if weeknumber > 1 then date = date + ((weeknumber - 1) * (7 * ONE_DAY)) end else -- find the first day of the next month while dateparts["month"]
-- go back one day to get the last day of the month we want date = date - ONE_DAY dateparts = os.date("*t", date)
-- go backwards until we find the right day of week while dateparts["wday"] ~= dayofweek do date = date - ONE_DAY dateparts = os.date("*t", date) end end local result = os.date("%Y-%m-%d", date) return result
end
return p