Module:SBI date

-- (don't remove this; it prevents this module --     from being categorized unintentionally into --      wrong categories)

-- formats dates measured from the time of the steel bar incident

-- for month formatting local monthname = require("module:month name");

local m = {};

local function format_epoch(year, with_link) return (with_link and "" or "")        .. (year < 0 and "BSBI" or "ASBI")         .. (with_link and "" or ""); end

local function getmonth(month) if month == "?" then return month; else return monthname.getmonth(month); end end

local function print_date(day, month, year, with_link) local print_comma = (day or month) and year; local print_space_after_month = month and day; return (month and (month == "?" and month or monthname.getmonth(month)) or "") .. (print_space_after_month and " " or "") .. (day or "") .. (print_comma and ", " or "") .. (year and (year == "?" and year or math.abs(year)) or "") .. (year and year ~= "?" and " " .. format_epoch(year, with_link) or ""); end

-- formats a date -- expects numbers or "?" function m.format_date(day, month, year, with_link) day = day or "?"; month = month or "?"; if day == "?" then day = nil; end if not day and month == "?" then month = nil end if not day and not month and not year then year = "?"; end return print_date(day, month, year, with_link); --[=[   local yearformat = ""; if year then yearformat = math.abs(year) .. " "            .. (with_link and "" or "")             .. (year < 0 and "BSBI" or "ASBI")             .. (with_link and "" or ""); end local daymonthformat = ""; local separator = ", "; if month then daymonthformat = monthname.getmonth(month); if day then daymonthformat = daymonthformat .. " " .. day; else separator = " "; end elseif day then daymonthformat = "? " .. day; end return daymonthformat .. ((daymonthformat ~= "" and yearformat ~= "") and separator or "") .. yearformat; ]=] end

--formats a date range --expects numbers function m.format_daterange(day_first, month_first, year_first, day_last, month_last, year_last, with_link)

-- if no second date given, just print a date if not day_last and not month_last and not year_last then return m.format_date(day_first, month_first, year_first, with_link); end local year_first2 = year_first or year_last or "?"; local year_last2 = year_last or year_first2; local month_first2 = month_first or month_last or "?"; local month_last2 = month_last or month_first2; local day_first2 = day_first or day_last or "?"; local day_last2 = day_last or day_first2; local print_year_first, print_year_last, print_month_first, print_month_last, print_day_first, print_day_last; print_year_last = year_first or year_last; print_year_first = year_first2 ~= year_last2 or (year_first == "?" and year_last == "?"); -- if years differ, don't merge the month and day fields if print_year_first then month_first2 = month_first or "?"; month_last2 = month_last or "?"; day_first2 = day_first or "?"; day_last2 = day_last or "?"; end print_month_first = month_first2 ~= "?" or day_first2 ~= "?"; print_month_last = print_year_first and (month_last2 ~= "?" or day_last2 ~= "?") or not print_year_first and (month_first2 ~= month_last2 or month_first == "?" and month_last == "?"); -- if months differ, don't merge the day fields if print_month_last then day_first2 = day_first or "?"; day_last2 = day_last or "?"; end print_day_last = day_last2 ~= "?"; print_day_first = print_month_last and (day_first2 ~= "?") or not print_month_last and day_first2 ~= day_last2; local first_date, last_date; if (print_day_last and day_last2) == "?" or (print_day_first and day_first2) == "?" or (print_month_last and print_year_last and month_last2) == "?" or (print_month_first and print_year_last and month_first2) == "?" or (print_year_first and year_first2) == "?" then -- print full dates if there is one wild card to be printed (else it becomes ambiguous) -- only exception is a single (!) wildcard in the year specification -- or no date is printed at all first_date = m.format_date(day_first2, month_first2, year_first2, with_link); last_date = m.format_date(day_last2, month_last2, year_last2, with_link); else -- else print partial dates as specified first_date = print_date(print_day_first and day_first2,			print_month_first and month_first2,			print_year_first and year_first2,			with_link); last_date = print_date(print_day_last and day_last2,			print_month_last and month_last2,			print_year_last and year_last2,			with_link); end if first_date == last_date then return first_date; end if first_date == "" then return last_date; end if last_date == "" then return first_date; end return first_date .. " - " .. last_date; end

--[[ old version function m.format_daterange(day_begin, month_begin, year_begin, day_end, month_end, year_end, with_link)	local year_end2 = year_end or year_begin;   local year_begin2 = year_begin or year_end;	local month_begin2 = month_begin or month_end;	local month_end2 = month_end or month_begin;	local day_begin2 = day_begin or day_end;	local day_end2 = day_end or day_begin;    if year_begin2 then        table.insert(end_date, year_end2 == "?" and year_end2 or tostring(math.abs(year_end)));        if year_end2 ~= "?" then			table.insert(end_date, format_epoch(year_end, with_link));		end        if year_begin ~= "?" and year_begin < 0 and year_end >= 0 then            table.insert(begin_date, format_epoch(year_begin == "?" and 0 or year_begin, with_link));        end        if (year_begin == "?" and year_end) or year_begin ~= year_end2 then            table.insert(begin_date, 1, tostring(year_begin == "?" and year_begin or math.abs(year_begin)));            agree_upto_here = false;        end    end    if month_begin2 then		if not agree_upto_here then			-- spell out end date			if month_end and month_end ~= "?" or day_end and day_end ~= "?" then				table.insert(end_date, 1, (not month_end or month_end == "?") and "?" or monthname.getmonth(month_end));				if day_end and day_end ~= "?" then					table.insert(end_date, 2, tostring(day_end) .. ",");				end			end			-- spell out start date			if month_begin and month_begin ~= "?" or day_begin and day_begin ~= "?" then				table.insert(begin_date, 1, (not month_begin or month_begin == "?") and "?" or monthname.getmonth(month_begin));				if day_begin and day_begin ~= "?" then					table.insert(begin_date, 2, tostring(day_begin) .. ",");				end			end		else			-- same year			-- check if it specifies the same day and month or if month and day are unspecified			if day_begin2 == day_end2 and month_begin2 == month_end2 then				--same month, no day specified				if month_begin2 ~= "?" and (not day_begin2 or day_begin2 == "?") then					table.insert(end_date, 1, monthname.getmonth(month_begin2));				--same month, same day				elseif month_begin2 ~= "?" and day_begin2 and day_begin2 ~= "?" then					table.insert(end_date, 1, monthname.getmonth(month_begin2));					table.insert(end_date, 2, tostring(day_begin2) .. ",");				--unspecified month, same day				elseif month_begin2 == "?" and day_begin2 and day_begin2 ~= "?" then					--  both months explicitly unspecified					if month_begin == "?" and month_end == "?" then						--both days explicitly specified						if day_begin and day_end then							table.insert(begin_date, "?");							table.insert(begin_date, tostring(day_begin2));							table.insert(end_date, 1, "?");							table.insert(end_date, 2, tostring(day_end2));						--one day explicitly specified						else							table.insert(begin_date, "?");							if day_begin then								table.insert(begin_date, day_begin .. ",");							end							for _, v in ipairs(end_date) do								table.insert(begin_date, v);							end							table.insert(end_date, 1, "?");							if day_end then								table.insert(end_date, day_end .. ",");							end						end					end				--unspecified month, unspecified day				else					-- we don't have to do anything				end			-- check if we have the same month, but different days			elseif month_begin2 == month_end2 and month_begin ~= "?" and month_end ~= "?" and day_begin2 ~= day_end2 then				table.insert(begin_date, 1, month_begin2 == "?" and "?" or monthname.getmonth(month_begin2));				table.insert(begin_date, 2, tostring(day_begin2));				table.insert(end_date, 1, tostring(day_end2) .. ",");			-- different months			elseif month_begin2 ~= month_end2 then				table.insert(begin_date, 1, month_begin2);				if day_begin and day_begin ~= "?" and month_end2 == "?" then 					table.insert(begin_date, 2, day_begin .. ",");					for _, v in ipairs(end_date) do						table.insert(begin_date, v);					end				else					table.insert(begin_date, 2, day_begin);				end				table.insert(end_date, 1, month_end2);				if day_end and day_end ~= "?" then					table.insert(end_date, 2, day_end .. ",");				end			end		end	elseif day_begin2 ~= day_end2 then		table.insert(end_date, 1, tostring(day_end2) .. ",");		table.insert(begin_date, 1, "?");		if not agree_upto_here then			table.insert(begin_date, 2, tostring(day_begin2) .. ",");		else			table.insert(begin_date, 2, tostring(day_begin2));		end    end	if #begin_date > 0 then		return table.concat(begin_date, " ") .. " - " .. table.concat(end_date, " ");    else		return table.concat(end_date, " ");	end end ]]

-- tests if the value is nil, false or "" local function isempty(x) return not x or x == ""; end

local function numorunspecifiedvalue(x) if isempty(x) then return nil; end if x == "?" then return x;   end local val = tonumber(x); return val, val == nil; end

--functions that form the interface to the templates --date template function m.format_date_template(frame) local args = frame.args; local year, err1 = numorunspecifiedvalue(args[1]); local month, err2 = numorunspecifiedvalue(args[2]); local day, err3 = numorunspecifiedvalue(args[3]); local put_link = args[4] ~= "no" and args[4] ~= "false"; if err1 or err2 or err3 or (not year and not month and not day) then return ' Date error ' .. ' ';   end return m.format_date(day, month, year, put_link); end

--date range template function m.format_daterange_template(frame) local args = frame.args; local year_first, err1 = numorunspecifiedvalue(args[1]); local month_first, err2 = numorunspecifiedvalue(args[2]); local day_first, err3 = numorunspecifiedvalue(args[3]); local year_last, err4 = numorunspecifiedvalue(args[4]); local month_last, err5 = numorunspecifiedvalue(args[5]); local day_last, err6 = numorunspecifiedvalue(args[6]); local put_link = args[7] ~= "no" and args[7] ~= "false"; if err1 or err2 or err3 or err4 or err5 or err6 or       (not year_first and not month_first and not day_first and            not year_last and not month_last and not day_last) then return ' Date range error ' .. ' ';   end return m.format_daterange(               day_first, month_first, year_first,                day_last, month_last, year_last,                put_link            ); end

return m;

--