Module:Calendar widget

This is an old revision of this page, as edited by RexxS (talk | contribs) at 19:59, 29 June 2019 (array index). The present address (URL) is a permanent link to this revision, which may differ significantly from the current revision.

--[[
Module to create Calendar widget

--]]

local p = {}

local daysinmonth = {
	31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
}
local dayname = {
	"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"
}
local dayabbr = {}
for i, v in ipairs(dayname) do
	dayabbr[i] = v:sub(1, 2)
end
local monthname = {
	"January", "February", "March", "April", "May", "June",
	"July", "August", "September", "October", "November", "December"
}
local monthabbr = {}
for i, v in ipairs(monthname) do
	monthabbr[i] = v:sub(1, 3)
end
local monthnumber = {}
for i, v in ipairs(monthabbr) do
	monthnumber[v] = i
end
local thisyear = os.date("*t").year

local function isleap(year)
	year = tonumber(year) or 1
	return year % 4 == 0
	and year % 100 ~= 0
	or year % 1000 == 0
end

--[[
Sakamoto's method: 1 <= month <= 12; year is Gregorian
dayofweek returns 1 to 7 or nil if bad arguments
--]]
local function dayofweek(year, month, day)
	local y = tonumber(year)
	local m = tonumber(month)
	local d = tonumber(day)
	if not (y and m and d) then return nil end
	local t = {0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4}
	if m < 3 then y = y - 1 end
	return (y + math.floor(y/4) - math.floor(y/100) + math.floor(y/400) + t[m] + d) % 7 + 1
end

local function monthstart(year, month)
	return dayofweek(year, month, 1)
end

local function calendar(args)
	local year = args.year or thisyear
	local month = args.month
	if tonumber(month) then month = monthname[month] end
	local out = {}
	
	out[1] = args.month
	out[2] = args.year
	return table.concat(out, " ")
end

--[[
Sakamoto's method: ISO date
returns day name or nil if bad arguments
--]]
function p.dayofweek(frame)
	local isodate = mw.text.trim(frame.args[1] or "")
	local y, m, d = isodate:match("(%d+)%p(%d+)%p(%d+)")
	local dow = dayofweek(y, m, d)
	if not dow then return "" end
	return dayname[dow]
end

--[[
isleap returns "leap" if passed a leap year
otherwise returns nothing
]]
function p.isleap(frame)
	if isleap(frame.args[1]) then return "leap" end
	return ""
end

--[[
Main entry point for widget
--]]
function p.calendar(frame)
	local args = frame.args
	--[[
	if not next(args) then
		args = frame:getParent().args
	end
	-- set empty args to be nil
	for k, v in pairs(args) do
		if v == "" then args[k] = nil end
	end
	--]]
	return calendar(args)
end


return p