Module:Birth based on age as of dates

From Doc-Wiki
Revision as of 14:19, 1 January 2026 by Docmoates (talk | contribs) (1 revision imported)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

Documentation for this module may be created at Module:Birth based on age as of dates/doc

local yesno = require('Module:Yesno')

local p = {} --p stands for package

local getArgs = require('Module:Arguments').getArgs

local function month_number(text)
	month_numbers = {
		jan = 1, january = 1,
		feb = 2, february = 2,
		mar = 3, march = 3,
		apr = 4, april = 4,
		may = 5,
		jun = 6, june = 6,
		jul = 7, july = 7,
		aug = 8, august = 8,
		sep = 9, september = 9, sept = 9,
		oct = 10, october = 10,
		nov = 11, november = 11,
		dec = 12, december = 12,
	}
	return tonumber(text) or month_numbers[text:lower():gsub('%.', '')]
end

function p.main( frame )
	local args = getArgs(frame)
	return p.date(args)
end

function p.date( args )
	if args[4] then
		args[3] = month_number(args[3])
		date_latest = os.time({year = args[2] - args[1], month = args[3], day = args[4]}) --we compute the latest possible birthdate based on the first give data point
		date_earliest = os.time({year = args[2] - args[1] - 1, month = args[3], day = args[4] + 1})
	elseif args[3] then
		args[3] = month_number(args[3])
		date_latest = os.time({year = args[2] - args[1], month = args[3] + 1, day = 0}) --gets the last day of the month
		date_earliest = os.time({year = args[2] - args[1] - 1, month = args[3], day = 2})
	else
		date_latest = os.time({year = args[2] - args[1], month = 12, day = 31})
		date_earliest = os.time({year = args[2] - args[1] - 1, month = 1, day = 2})
	end
	
	--then we loop on other given datapoints to triangulate the date
	frame_arg = 5
	while args[frame_arg + 3] ~= nil do
		args[frame_arg + 2] = month_number(args[frame_arg + 2])
		date_latest_new = os.time({year = args[frame_arg + 1] - args[frame_arg], month = args[frame_arg + 2], day = args[frame_arg + 3]})
		date_latest = math.min(date_latest, date_latest_new)
		date_earliest_new = os.time({year = args[frame_arg + 1] - args[frame_arg] - 1, month = args[frame_arg + 2], day = args[frame_arg + 3]}) + 86402
		date_earliest = math.max(date_earliest, date_earliest_new)
		frame_arg = frame_arg + 4
	end
	
	--we check if the calculated birth year is the same
	if os.date("%Y", date_earliest) == os.date("%Y", date_latest) then
		birth_year_string = os.date("%Y", date_earliest)
	elseif yesno(args["slash"] or false) then
		birth_year_string = os.date("%Y", date_earliest) .. "/" .. os.date("%Y", date_latest)
	else
		birth_year_string = os.date("%Y", date_earliest) .. " or " .. os.date("%Y", date_latest)
	end
	
	--then we convert back to a time table to see if the person is past their birthday
	birthday_earliest = {year = os.date("%Y", os.time()), month = os.date("%m", date_earliest), day = os.date("%d", date_earliest)}
	birthday_latest = {year = os.date("%Y", os.time()), month = os.date("%m", date_latest), day = os.date("%d", date_latest)}
	
	if yesno(args.noage or false) then
		full_string = birth_year_string
	else
		if os.date("%Y", date_earliest) == os.date("%Y", date_latest) then
			year_diff = os.date("%Y", os.time()) - os.date("%Y", date_latest)
			if os.time() < os.time(birthday_earliest) then
				full_string = birth_year_string .. " (age&nbsp;" .. year_diff-1 .. ")"
			elseif os.time() < os.time(birthday_latest) then
				full_string = birth_year_string .. " (age&nbsp;" .. year_diff-1 .. "–" .. year_diff .. ")"
			else
				full_string = birth_year_string .. " (age&nbsp;" .. year_diff .. ")"
			end
		else
			year_diff = os.date("%Y", os.time()) - os.date("%Y", date_latest)
			if os.time() < os.time(birthday_latest) then
				full_string = birth_year_string .. " (age&nbsp;" .. year_diff-1 .. "–" .. year_diff .. ")"
			elseif os.time() < os.time(birthday_earliest) then
				full_string = birth_year_string .. " (age&nbsp;" .. year_diff .. ")"
			else
				full_string = birth_year_string .. " (age&nbsp;" .. year_diff .. "–" .. year_diff+1 .. ")"
			end
		end
	end
	
    return full_string
end

return p