Module:Person date
Appearance
From Wikipedia, the free encyclopedia
This is the current revision of this page, as edited by Zackmann08 (talk | contribs) at 18:05, 19 October 2025 (Account for the presence of disappeared_date per this thread). The present address (URL) is a permanent link to this version.Revision as of 18:05, 19 October 2025 by Zackmann08 (talk | contribs) (Account for the presence of disappeared_date per this thread)
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.
Page template-protected 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.
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.
Warning This Lua module is used on approximately 1,720,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.
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|}}}|<divstyle="display:inline"class="nickname">{{{birth_name|}}}</div>}} |2={{#invoke:person date|birth}} |3={{#if:{{{birth_place|}}}|<divclass="birthplace">{{{birth_place|}}}</div>}} }} | label# = Died | data# = {{br separated entries |1={{#invoke:person date|death}} |2={{#if:{{{death_place|}}}|<divclass="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
The above documentation is transcluded from Module:Person date/doc. (edit | history)
Editors can experiment in this module's sandbox (edit | diff) and testcases (edit | run) pages.
Subpages of this module.
Editors can experiment in this module's sandbox (edit | diff) and testcases (edit | run) pages.
Subpages of this module.
require("strict") localp={} localTEMPLATES={ birth_date="Birth date", birth_date_and_age="Birth date and age", birth_year="Birth year", birth_year_and_age="Birth year and age", death_date="Death date", death_date_text="Death date text", death_date_and_age="Death date and age", death_year="Death year", death_year_and_age="Death year and age", } localinvalid_date_category='' localtracking_category='' localDate=require('Module:Date')._Date localgetArgs=require('Module:Arguments').getArgs ifmw.title.getCurrentTitle():inNamespaces(0,828,829)then -- Category only in namespaces: 0=article, 828=module & 829=module talk (last 2 needed for testcases) tracking_category='[[Category:Pages where birth or death is being automatically determined]]' invalid_date_category='[[Category:Pages with invalid birth or death dates]]' end localfunctioncheck_for_invalid_date(str) returnmw.ustring.match(str,'^%?')ormw.ustring.match(str,'^%d%d%?')ormw.ustring.match(str,'^[Uu]nk') end localfunctionexpand_template(template,args) returnmw.getCurrentFrame():expandTemplate{title=template,args=args} end localfunctionparse_date(str) localdate=Date(str) ifdatethen returntostring(date.year),tostring(date.month),tostring(date.day) end -- TODO: Date has not been parsed. Need to work out what to do. For now, throw an error. -- Example where this can occur: "birth_date = 22 December 1946" at [[Maurice Pasternak]]. -- There was a nonbreaking space after "22" whidh Date does not accept. error('Module:Person_date parse_date invalid date: "'..tostring(str)..'"') end localfunctiondate_format(str) ifmw.ustring.match(str,'^%d+%s*%a+[%.]*%s*%d%d%d%d$')then return'df' elseifmw.ustring.match(str,'^%a+[%.]*%s+%d+,%s*%d%d%d%d$')then return'mf' else return'ERROR' end end localfunctionis_valid_month(str) str=string.upper(mw.ustring.sub(str,1,1))..string.lower(mw.ustring.sub(str,2)) localmonths={'Jan','Jan.','January','Feb','Feb.','February','Mar','March','Apr','Apr.','April','May','Jun','Jun.','June','Jul','Jul.','July','Aug','Aug.','August','Sep','Sept','Sep.','Sept.','September','Oct','Oct.','October','Nov','Nov','November','Dec','Dec.','December'} forindex,valueinipairs(months)do ifvalue==strthen returntrue end end returnfalse end localfunctionis_month_year_only(str) localmonth=mw.ustring.match(str,'^(%a+)[%.]*%s+%d%d%d%d$') ifmonth==nilthen returnfalse else returnis_valid_month(month) end end localfunctionis_valid_date(str) localmonth=mw.ustring.match(str,'^%d+%s*(%a+)[%.]*%s*%d%d%d%d$')ormw.ustring.match(str,'^(%a+)[%.]*%s+%d+,%s*%d%d%d%d$') ifmonth==nilthen returnfalse else returnis_valid_month(month) end end localfunctionis_year_only(str) returnmw.ustring.match(str,'^%d%d%d%d$') end localfunctionalready_has_template(str) str=mw.ustring.gsub(str,'&[Nn][Bb][Ss][Pp];',' ') returnmw.ustring.match(str,'<span')ormw.ustring.match(str,'<time')ormw.ustring.match(str,'%(aged%s*%d+')ormw.ustring.match(str,'%(age%s*%d+') end localfunctionsanatize_date(str) -- Sanatize leading & trailing whitespace (this caused an issue before it was implemented) str=mw.ustring.gsub(str,'^%s*','') str=mw.ustring.gsub(str,'%s*$','') -- Sanatize ordinals str=mw.ustring.gsub(str,'(%d+)st([,%s])','%1%2') str=mw.ustring.gsub(str,'(%d+)rd([,%s])','%1%2') str=mw.ustring.gsub(str,'(%d+)th([,%s])','%1%2') str=mw.ustring.gsub(str,'(%d+)nd([,%s])','%1%2') returnstr end localfunctionparse_birth(args) localbirth_date=args['birth_date']orargs[1]or'' localdeath_date=args['death_date']orargs[2]or'' localdisap_date=args['disappeared_date']or'' localoriginal=birth_date birth_date=sanatize_date(birth_date) death_date=sanatize_date(death_date) disap_date=sanatize_date(disap_date) -- Check for bad inputs. This used to be covered by a switch statement in infoboxes ifcheck_for_invalid_date(birth_date)then returnoriginal..invalid_date_category end ifalready_has_template(birth_date)then returnoriginal end ifis_valid_date(birth_date)then locallocation=mw.ustring.find(birth_date,'%d%d%d%d') localextra=mw.ustring.sub(birth_date,location+4)..tracking_category localdate=mw.ustring.sub(birth_date,1,location+3) localyear,month,day=parse_date(date) localformat=date_format(date) ifdeath_date==''anddisap_date==''then returnexpand_template(TEMPLATES.birth_date_and_age,{year,month,day,[format]='yes'})..extra elseifis_year_only(death_date)oris_valid_date(death_date)oris_month_year_only(death_date)then returnexpand_template(TEMPLATES.birth_date,{year,month,day,[format]='yes'})..extra else -- death_date is not a valid string (example: 'unknown') returnoriginal end end ifis_month_year_only(birth_date)then localyear=Date('1 '..birth_date):text('%Y') localmonth=Date('1 '..birth_date):text('%-m') locallocation=mw.ustring.find(birth_date,'%d%d%d%d') localdate=mw.ustring.sub(birth_date,1,location+3) localextra=mw.ustring.sub(birth_date,location+4)..tracking_category ifdeath_date==''anddisap_date==''then returnexpand_template(TEMPLATES.birth_year_and_age,{year,month})..extra elseifis_year_only(death_date)oris_valid_date(death_date)oris_month_year_only(death_date)then returnexpand_template(TEMPLATES.birth_year,{date})..extra else -- death_date is not a valid string (example: 'unknown') returnoriginal end end ifis_year_only(birth_date)then localdate=mw.ustring.sub(birth_date,1,5) localextra=mw.ustring.sub(birth_date,5)..tracking_category ifdeath_date==''anddisap_date==''then returnexpand_template(TEMPLATES.birth_year_and_age,{date})..extra elseifis_year_only(death_date)oris_valid_date(death_date)then returnexpand_template(TEMPLATES.birth_year,{date})..extra else -- death_date is not a valid string (example: 'unknown') returnoriginal end end returnoriginal end localfunctionparse_death(args) localbirth_date=args['birth_date']orargs[1]or'' localdeath_date=args['death_date']orargs[2]or'' localoriginal=death_date birth_date=sanatize_date(birth_date) death_date=sanatize_date(death_date) -- Check for bad inputs. This used to be covered by a switch statement in infoboxes ifcheck_for_invalid_date(death_date)then returnoriginal..invalid_date_category end ifalready_has_template(death_date)then returnoriginal end ifis_valid_date(death_date)oris_month_year_only(death_date)then locallocation=mw.ustring.find(death_date,'%d%d%d%d') localdate=mw.ustring.sub(death_date,1,location+3) localextra=mw.ustring.sub(death_date,location+4)..tracking_category localformat=date_format(date) ifbirth_date==''then ifis_month_year_only(death_date)then returnexpand_template(TEMPLATES.death_date_text,{date})..extra end localyear,month,day=parse_date(date) returnexpand_template(TEMPLATES.death_date,{year,month,day,[format]='yes'})..extra else ifis_year_only(birth_date)then location=mw.ustring.find(birth_date,'%d%d%d%d') localbd=mw.ustring.sub(birth_date,1,location+3) ifis_month_year_only(death_date)then returnexpand_template(TEMPLATES.death_date_and_age,{date,bd})..extra end returnexpand_template(TEMPLATES.death_date_and_age,{date,bd,[format]='yes'})..extra elseifis_valid_date(birth_date)oris_month_year_only(birth_date)then location=mw.ustring.find(birth_date,'%d%d%d%d') localbd=mw.ustring.sub(birth_date,1,location+3) if(is_month_year_only(death_date))then returnexpand_template(TEMPLATES.death_date_and_age,{date,bd})..extra end returnexpand_template(TEMPLATES.death_date_and_age,{date,bd,[format]='yes'})..extra end end end ifis_year_only(death_date)then ifbirth_date==''then returnexpand_template(TEMPLATES.death_year,{mw.ustring.sub(death_date,1,5)})..mw.ustring.sub(death_date,5)..tracking_category else ifis_year_only(birth_date)then returnexpand_template(TEMPLATES.death_year_and_age,{mw.ustring.sub(death_date,1,5),mw.ustring.sub(birth_date,1,5)})..mw.ustring.sub(death_date,5)..tracking_category else ifis_valid_date(birth_date)then locallocation=mw.ustring.find(death_date,'%d%d%d%d') localdate=mw.ustring.sub(death_date,1,location+3) localextra=mw.ustring.sub(death_date,location+4)..tracking_category location=mw.ustring.find(birth_date,'%d%d%d%d') localbd=mw.ustring.sub(birth_date,1,location+3) returnexpand_template(TEMPLATES.death_date_and_age,{date,bd})..extra end end end end returnoriginal end functionp.birth(frame) returnparse_birth(getArgs(frame,{parentFirst=true})) end functionp.death(frame) returnparse_death(getArgs(frame,{parentFirst=true})) end returnp