Module:Age
Appearance
Documentation for this module may be created at Module:Age/doc
-- Module:Age
-- Provides age calculations for {{age}}, {{death date and age}}, {{birth date and age}}
-- and the date handling in {{Infobox person}} / {{Infobox scientist}}.
--
-- Entry point used on this wiki:
-- {{#invoke:age|age_generic|template=age_full_years}}
-- called from Template:Age, whose parent parameters are:
-- 1,2,3 = year, month, day of the earlier date
-- 4,5,6 = year, month, day of the later date (defaults to today if omitted)
local p = {}
-- Convert a parameter to a number, tolerating whitespace, empty strings and nil.
local function num(v)
if v == nil then
return nil
end
v = tostring(v):match('^%s*(.-)%s*$')
if v == '' then
return nil
end
return tonumber(v)
end
-- Whole years elapsed from (y1,m1,d1) to (y2,m2,d2).
local function fullYears(y1, m1, d1, y2, m2, d2)
local age = y2 - y1
if (m2 < m1) or (m2 == m1 and d2 < d1) then
age = age - 1
end
return age
end
-- Collect the six date parameters, preferring the parent frame (the template call),
-- falling back to direct #invoke arguments so the module can also be called directly.
local function getDates(frame)
local args = {}
local parent = frame:getParent()
if parent and parent.args then
for i = 1, 6 do
args[i] = parent.args[i]
end
end
for i = 1, 6 do
if num(args[i]) == nil then
args[i] = frame.args[i] or args[i]
end
end
local y1, m1, d1 = num(args[1]), num(args[2]), num(args[3])
local y2, m2, d2 = num(args[4]), num(args[5]), num(args[6])
-- No later date supplied: measure to today.
if y2 == nil then
local now = os.date('*t')
y2, m2, d2 = now.year, now.month, now.day
end
-- Missing month/day default to the start of the year, matching the
-- behaviour the wrapper templates expect when they pass partial dates.
m1, d1 = m1 or 1, d1 or 1
m2, d2 = m2 or 1, d2 or 1
return y1, m1, d1, y2, m2, d2
end
function p.age_generic(frame)
local y1, m1, d1, y2, m2, d2 = getDates(frame)
if y1 == nil then
return ''
end
local age = fullYears(y1, m1, d1, y2, m2, d2)
-- Guard against obviously bad input rather than emitting a negative age.
if age < 0 or age > 150 then
return ''
end
return tostring(age)
end
-- Aliases, so other standard wrappers work if they are ever imported.
p.age_full_years = p.age_generic
p.main = p.age_generic
return p