Module:Person date
Appearance
| This module is rated as ready for general use. It has reached a mature state, is considered relatively stable and bug-free, and may be used wherever appropriate. It can be mentioned on help pages and other Wikipedia resources as an option for new users. To minimise server load and avoid disruptive output, improvements should be developed through sandbox testing rather than repeated trial-and-error editing. |
| This module is currently protected from editing. See the protection policy and protection log for more details. Please discuss any changes on the talk page; you may submit an edit request to ask an administrator to make an edit if it is uncontroversial or supported by consensus. You may also request that this page be unprotected. |
| This Lua module is used on approximately 1,730,000 pages, or roughly 3% of all pages. To avoid major disruption and server load, any changes should be tested in the module's /sandbox or /testcases subpages, or in your own module sandbox. The tested changes can be added to this page in a single edit. Consider discussing changes on the talk page before implementing them. |
This module is intended to aid in calculating/formatting birth dates and death dates in {{Infobox person}} and other People and person infobox templates.
This module generates errors when it encounters invalid input. Error descriptions and how to fix them are listed at Category:Pages using age template with invalid date.
Usage
{{#invoke:person date|birth}}{{#invoke:person date|death}}
In infoboxes
{{Infobox
...
| label# = Born
| data# = {{#invoke:person date|birth}}
| label# = Died
| data# = {{#invoke:person date|death}}
...
}}
Or
{{Infobox
...
| label# = Born
| data# = {{br separated entries
|1={{#if:{{{birth_name|}}}|<div style="display:inline" class="nickname">{{{birth_name|}}}</div>}}
|2={{#invoke:person date|birth}}
|3={{#if:{{{birth_place|}}}|<div class="birthplace">{{{birth_place|}}}</div>}}
}}
| label# = Died
| data# = {{br separated entries
|1={{#invoke:person date|death}}
|2={{#if:{{{death_place|}}}|<div class="deathplace">{{{death_place|}}}</div>}}
}}
...
}}
Areas for improvement
- Currently the module does not handle anything that is not a simple date. So anything with a reference tag is not evaluated by the code.
- If
|birth_date=(for example) then{{bda|1993|11|7}}|death_date=will not be parsed. It will just be returned as the original string. Thus no age is calculated.
Tracking categories
local p = {}
local MAX_AGE = 130
local error_text = 'Error: Invalid birth_date in [[Module:Person date]], violates MAX_AGE of '.. MAX_AGE
local category_text = '[[Category:Articles using module person date older than 130]]'
function is_valid_month (str)
local months = {'Jan','January','Feb','February','Mar','March','Apr','April','May','Jun','June','Jul','July','Aug','August','Sep','September','Oct','October','Nov','November','Dec','December'}
for index, value in ipairs(months) do
if value == str then
return true
end
end
return false
end
function is_valid_date(str)
local month = mw.ustring.match (str, '^%d+%s*(%a+)%s*%d%d%d%d') or mw.ustring.match(str, '^(%a+)%s+%d+,%s*%d%d%d%d') or mw.ustring.match(str, '^(%a+)%s+%d%d%d%d')
return is_valid_month(month)
end
function is_year_only(str)
return mw.ustring.match(str, '^%s*%d%d%d%d%s*')
end
function already_has_template(str)
return mw.ustring.match(str, '<span') or mw.ustring.match(str, '<time')
end
function parse_birth(frame, args)
local birth_date = args[1] or ''
local death_date = args[2] or ''
local original = birth_date
-- Sanatize leading whitespace (this caused an issue before it was implemented)
birth_date = mw.ustring.gsub(birth_date,'^%s*','')
death_date = mw.ustring.gsub(death_date,'^%s*','')
if already_has_template(birth_date) then
return original
end
if is_valid_date(birth_date) then
local location = mw.ustring.find(birth_date, '%d%d%d%d')
local date = mw.ustring.sub(birth_date, 1,location+3)
local extra = mw.ustring.sub(birth_date, location+4)
if death_date == '' then
return frame:expandTemplate{ title = 'Birth date and age text', args = {date}} .. extra
else
return frame:expandTemplate{ title = 'Birth date text', args = {date}} .. extra
end
end
if is_year_only(birth_date) then
if death_date == '' then
return frame:expandTemplate{ title = 'bya', args = {mw.ustring.sub(birth_date, 1, 5)}} .. mw.ustring.sub(birth_date, 5)
else
return frame:expandTemplate{ title = 'birth year', args = {mw.ustring.sub(birth_date, 1, 5)}} .. mw.ustring.sub(birth_date, 5)
end
end
return original
end
function parse_death(frame, args)
local birth_date = args[1] or ''
local death_date = args[2] or ''
local original = death_date
-- Sanatize leading whitespace (this caused an issue before it was implemented)
birth_date = mw.ustring.gsub(birth_date,'^%s*','')
death_date = mw.ustring.gsub(death_date,'^%s*','')
if already_has_template(death_date) then
return original
end
if is_valid_date(death_date) then
local location = mw.ustring.find(death_date, '%d%d%d%d')
local date = mw.ustring.sub(death_date, 1,location+3)
local extra = mw.ustring.sub(death_date, location+4)
if birth_date == '' then
return frame:expandTemplate{ title = 'death date text', args = {date}} .. extra
else
if is_year_only(birth_date) then
location = mw.ustring.find(birth_date, '%d%d%d%d')
bd = mw.ustring.sub(birth_date, 1,location+3)
return frame:expandTemplate{ title = 'Death date and age text', args = {date, bd}} .. extra
else
if is_valid_date(birth_date) then
location = mw.ustring.find(birth_date, '%d%d%d%d')
bd = mw.ustring.sub(birth_date, 1,location+3)
return frame:expandTemplate{ title = 'Death date and age text', args = {date, bd}} .. extra
end
end
end
end
if is_year_only(death_date) then
if birth_date == '' then
return frame:expandTemplate{ title = 'death year', args = {mw.ustring.sub(death_date, 1, 5)}} .. mw.ustring.sub(death_date, 5)
else
if is_year_only(birth_date) then
return frame:expandTemplate{ title = 'Death year and age', args = {mw.ustring.sub(death_date, 1, 5), mw.ustring.sub(birth_date, 1, 5)}} .. mw.ustring.sub(death_date, 5)
else
if is_valid_date(birth_date) then
local location = mw.ustring.find(death_date, '%d%d%d%d')
local date = mw.ustring.sub(death_date, 1,location+3)
local extra = mw.ustring.sub(death_date, location+4)
location = mw.ustring.find(birth_date, '%d%d%d%d')
bd = mw.ustring.sub(birth_date, 1,location+3)
return frame:expandTemplate{ title = 'Death date and age text', args = {date, bd}} .. extra
end
end
end
end
return original
end
function check_for_max_date_birth(frame, text)
local regex = 'age <span class="currentage"></span>%d+'
local start, stop = mw.ustring.find(text, regex)
if start == nil or stop == nil then
return text
end
local age = mw.ustring.sub(text, start+mw.ustring.len(regex)-3, stop)
local error_msg = frame:expandTemplate{ title = 'error', args = {error_text}}
local category = frame:expandTemplate{ title = 'user other', args = {category_text}}
if tonumber(age) > MAX_AGE then
return text..error_msg..category
end
return text
end
function check_for_max_date_death(frame, text)
local regex = 'aged %d+'
local start, stop = mw.ustring.find(text, regex)
if start == nil or stop == nil then
return text
end
local age = mw.ustring.sub(text, start+mw.ustring.len(regex)-3, stop)
local error_msg = frame:expandTemplate{ title = 'error', args = {error_text}}
local category = frame:expandTemplate{ title = 'main other', args = {category_text}}
if tonumber(age) > MAX_AGE then
return text..error_msg..category
end
return text
end
function p.birth(frame)
text = parse_birth(frame, frame.args[1] and frame.args or frame:getParent().args)
return check_for_max_date_birth(frame, text)
end
function p.death(frame)
text = parse_death(frame, frame.args[1] and frame.args or frame:getParent().args)
return check_for_max_date_death(frame, text)
end
return p