<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="ja">
	<id>https://wiki1.koushin.ch/w/index.php?action=history&amp;feed=atom&amp;title=%E3%83%A2%E3%82%B8%E3%83%A5%E3%83%BC%E3%83%AB%3AAgeEstimator</id>
	<title>モジュール:AgeEstimator - 版の履歴</title>
	<link rel="self" type="application/atom+xml" href="https://wiki1.koushin.ch/w/index.php?action=history&amp;feed=atom&amp;title=%E3%83%A2%E3%82%B8%E3%83%A5%E3%83%BC%E3%83%AB%3AAgeEstimator"/>
	<link rel="alternate" type="text/html" href="https://wiki1.koushin.ch/w/index.php?title=%E3%83%A2%E3%82%B8%E3%83%A5%E3%83%BC%E3%83%AB:AgeEstimator&amp;action=history"/>
	<updated>2026-09-29T03:25:13Z</updated>
	<subtitle>このウィキのこのページに関する変更履歴</subtitle>
	<generator>MediaWiki 1.43.9</generator>
	<entry>
		<id>https://wiki1.koushin.ch/w/index.php?title=%E3%83%A2%E3%82%B8%E3%83%A5%E3%83%BC%E3%83%AB:AgeEstimator&amp;diff=10&amp;oldid=prev</id>
		<title>エーデルメーア: ページの作成:「-- Module:AgeEstimator local p = {}  local function trim(s)     if s == nil then return &#039;&#039; end     s = tostring(s)     return mw.ustring.gsub(s, &#039;^%s*(.-)%s*$&#039;, &#039;%1&#039;) end  -- 実質的な情報を含まない値（プレースホルダー）かどうか local function isPlaceholder(s)     s = trim(s)     if s == &#039;&#039; then return true end     if mw.ustring.match(s, &#039;^[%-_%s%.•・、。，,．－ー–—／/　]+$&#039;) then         return true     end     local lower =…」</title>
		<link rel="alternate" type="text/html" href="https://wiki1.koushin.ch/w/index.php?title=%E3%83%A2%E3%82%B8%E3%83%A5%E3%83%BC%E3%83%AB:AgeEstimator&amp;diff=10&amp;oldid=prev"/>
		<updated>2026-09-28T05:44:58Z</updated>

		<summary type="html">&lt;p&gt;ページの作成:「-- Module:AgeEstimator local p = {}  local function trim(s)     if s == nil then return &amp;#039;&amp;#039; end     s = tostring(s)     return mw.ustring.gsub(s, &amp;#039;^%s*(.-)%s*$&amp;#039;, &amp;#039;%1&amp;#039;) end  -- 実質的な情報を含まない値（プレースホルダー）かどうか local function isPlaceholder(s)     s = trim(s)     if s == &amp;#039;&amp;#039; then return true end     if mw.ustring.match(s, &amp;#039;^[%-_%s%.•・、。，,．－ー–—／/　]+$&amp;#039;) then         return true     end     local lower =…」&lt;/p&gt;
&lt;p&gt;&lt;b&gt;新規ページ&lt;/b&gt;&lt;/p&gt;&lt;div&gt;-- Module:AgeEstimator&lt;br /&gt;
local p = {}&lt;br /&gt;
&lt;br /&gt;
local function trim(s)&lt;br /&gt;
    if s == nil then return &amp;#039;&amp;#039; end&lt;br /&gt;
    s = tostring(s)&lt;br /&gt;
    return mw.ustring.gsub(s, &amp;#039;^%s*(.-)%s*$&amp;#039;, &amp;#039;%1&amp;#039;)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- 実質的な情報を含まない値（プレースホルダー）かどうか&lt;br /&gt;
local function isPlaceholder(s)&lt;br /&gt;
    s = trim(s)&lt;br /&gt;
    if s == &amp;#039;&amp;#039; then return true end&lt;br /&gt;
    if mw.ustring.match(s, &amp;#039;^[%-_%s%.•・、。，,．－ー–—／/　]+$&amp;#039;) then&lt;br /&gt;
        return true&lt;br /&gt;
    end&lt;br /&gt;
    local lower = mw.ustring.lower(s)&lt;br /&gt;
    local nolist = {&amp;#039;不明&amp;#039;,&amp;#039;なし&amp;#039;,&amp;#039;無し&amp;#039;,&amp;#039;未知&amp;#039;,&amp;#039;未定&amp;#039;,&amp;#039;未詳&amp;#039;,&amp;#039;不詳&amp;#039;,&lt;br /&gt;
                    &amp;#039;unknown&amp;#039;,&amp;#039;n/a&amp;#039;,&amp;#039;none&amp;#039;,&amp;#039;tbd&amp;#039;,&amp;#039;null&amp;#039;,&amp;#039;nil&amp;#039;}&lt;br /&gt;
    for _, w in ipairs(nolist) do&lt;br /&gt;
        if lower == w then return true end&lt;br /&gt;
    end&lt;br /&gt;
    return false&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local APPROX = {&lt;br /&gt;
    &amp;#039;前後&amp;#039;,&amp;#039;頃&amp;#039;,&amp;#039;ごろ&amp;#039;,&amp;#039;くらい&amp;#039;,&amp;#039;ぐらい&amp;#039;,&amp;#039;弱&amp;#039;,&amp;#039;強&amp;#039;,&amp;#039;約&amp;#039;,&lt;br /&gt;
    &amp;#039;およそ&amp;#039;,&amp;#039;大体&amp;#039;,&amp;#039;ほぼ&amp;#039;,&amp;#039;辺り&amp;#039;,&amp;#039;あたり&amp;#039;,&amp;#039;付近&amp;#039;,&lt;br /&gt;
    &amp;#039;大约&amp;#039;,&amp;#039;约&amp;#039;,&amp;#039;左右&amp;#039;,&amp;#039;前后&amp;#039;,&amp;#039;上下&amp;#039;,&lt;br /&gt;
    &amp;#039;약&amp;#039;,&amp;#039;정도&amp;#039;,&amp;#039;쯤&amp;#039;,&amp;#039;경&amp;#039;,&lt;br /&gt;
    &amp;#039;примерно&amp;#039;,&amp;#039;около&amp;#039;,&amp;#039;приблизительно&amp;#039;,&amp;#039;почти&amp;#039;,&amp;#039;с лишним&amp;#039;,&lt;br /&gt;
    &amp;#039;approximately&amp;#039;,&amp;#039;around&amp;#039;,&amp;#039;about&amp;#039;,&amp;#039;circa&amp;#039;,&amp;#039;-ish&amp;#039;,&amp;#039;or so&amp;#039;,&lt;br /&gt;
    &amp;#039;حوالي&amp;#039;,&amp;#039;نحو&amp;#039;,&amp;#039;قرابة&amp;#039;,&amp;#039;تقريبا&amp;#039;,&lt;br /&gt;
}&lt;br /&gt;
local EARLY = {&lt;br /&gt;
    &amp;#039;初め&amp;#039;,&amp;#039;初期&amp;#039;,&amp;#039;初頭&amp;#039;,&amp;#039;前半&amp;#039;,&amp;#039;上期&amp;#039;,&amp;#039;上半期&amp;#039;,&amp;#039;上半&amp;#039;,&amp;#039;前段&amp;#039;,&amp;#039;前叶&amp;#039;,&amp;#039;前葉&amp;#039;,&lt;br /&gt;
    &amp;#039;초반&amp;#039;,&amp;#039;초기&amp;#039;,&amp;#039;상반기&amp;#039;,&lt;br /&gt;
    &amp;#039;начало&amp;#039;,&amp;#039;начале&amp;#039;,&amp;#039;первая&amp;#039;,&amp;#039;первой&amp;#039;,&amp;#039;ранн&amp;#039;,&lt;br /&gt;
    &amp;#039;early&amp;#039;,&amp;#039;first&amp;#039;,&amp;#039;1st&amp;#039;,&lt;br /&gt;
    &amp;#039;المبكر&amp;#039;,&amp;#039;الأول&amp;#039;,&lt;br /&gt;
}&lt;br /&gt;
local MID = {&lt;br /&gt;
    &amp;#039;中頃&amp;#039;,&amp;#039;中ごろ&amp;#039;,&amp;#039;半ば&amp;#039;,&amp;#039;中盤&amp;#039;,&amp;#039;中期&amp;#039;,&amp;#039;中葉&amp;#039;,&lt;br /&gt;
    &amp;#039;중반&amp;#039;,&amp;#039;중기&amp;#039;,&lt;br /&gt;
    &amp;#039;середина&amp;#039;,&amp;#039;середине&amp;#039;,&amp;#039;средн&amp;#039;,&lt;br /&gt;
    &amp;#039;mid&amp;#039;,&amp;#039;middle&amp;#039;,&lt;br /&gt;
    &amp;#039;الأوسط&amp;#039;,&amp;#039;منتصف&amp;#039;,&lt;br /&gt;
}&lt;br /&gt;
local LATE = {&lt;br /&gt;
    &amp;#039;終わり&amp;#039;,&amp;#039;末期&amp;#039;,&amp;#039;終期&amp;#039;,&amp;#039;晩期&amp;#039;,&amp;#039;最末期&amp;#039;,&amp;#039;末&amp;#039;,&amp;#039;後半&amp;#039;,&amp;#039;下期&amp;#039;,&amp;#039;下半期&amp;#039;,&amp;#039;下半&amp;#039;,&amp;#039;後期&amp;#039;,&lt;br /&gt;
    &amp;#039;后期&amp;#039;,&amp;#039;末期&amp;#039;,&amp;#039;末&amp;#039;,&amp;#039;后半&amp;#039;,&lt;br /&gt;
    &amp;#039;후반&amp;#039;,&amp;#039;후기&amp;#039;,&amp;#039;하반기&amp;#039;,&lt;br /&gt;
    &amp;#039;конец&amp;#039;,&amp;#039;конце&amp;#039;,&amp;#039;конца&amp;#039;,&amp;#039;поздн&amp;#039;,&amp;#039;последн&amp;#039;,&amp;#039;вторая&amp;#039;,&amp;#039;второй&amp;#039;,&lt;br /&gt;
    &amp;#039;late&amp;#039;,&amp;#039;last&amp;#039;,&amp;#039;second&amp;#039;,&amp;#039;2nd&amp;#039;,&lt;br /&gt;
    &amp;#039;المتأخر&amp;#039;,&amp;#039;الأخير&amp;#039;,&amp;#039;الثاني&amp;#039;,&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
local MONTH_IN = {&lt;br /&gt;
    january=1, february=2, march=3, april=4, may=5, june=6,&lt;br /&gt;
    july=7, august=8, september=9, october=10, november=11, december=12,&lt;br /&gt;
    jan=1, feb=2, mar=3, apr=4, jun=6, jul=7, aug=8,&lt;br /&gt;
    sep=9, sept=9, oct=10, nov=11, dec=12,&lt;br /&gt;
    [&amp;#039;января&amp;#039;]=1, [&amp;#039;февраля&amp;#039;]=2, [&amp;#039;марта&amp;#039;]=3, [&amp;#039;апреля&amp;#039;]=4,&lt;br /&gt;
    [&amp;#039;мая&amp;#039;]=5, [&amp;#039;июня&amp;#039;]=6, [&amp;#039;июля&amp;#039;]=7, [&amp;#039;августа&amp;#039;]=8,&lt;br /&gt;
    [&amp;#039;сентября&amp;#039;]=9, [&amp;#039;октября&amp;#039;]=10, [&amp;#039;ноября&amp;#039;]=11, [&amp;#039;декабря&amp;#039;]=12,&lt;br /&gt;
    [&amp;#039;январь&amp;#039;]=1, [&amp;#039;февраль&amp;#039;]=2, [&amp;#039;март&amp;#039;]=3, [&amp;#039;апрель&amp;#039;]=4,&lt;br /&gt;
    [&amp;#039;май&amp;#039;]=5, [&amp;#039;июнь&amp;#039;]=6, [&amp;#039;июль&amp;#039;]=7, [&amp;#039;август&amp;#039;]=8,&lt;br /&gt;
    [&amp;#039;сентябрь&amp;#039;]=9, [&amp;#039;октябрь&amp;#039;]=10, [&amp;#039;ноябрь&amp;#039;]=11, [&amp;#039;декабрь&amp;#039;]=12,&lt;br /&gt;
    [&amp;#039;يناير&amp;#039;]=1, [&amp;#039;فبراير&amp;#039;]=2, [&amp;#039;مارس&amp;#039;]=3, [&amp;#039;أبريل&amp;#039;]=4, [&amp;#039;ابريل&amp;#039;]=4,&lt;br /&gt;
    [&amp;#039;مايو&amp;#039;]=5, [&amp;#039;يونيو&amp;#039;]=6, [&amp;#039;يوليو&amp;#039;]=7,&lt;br /&gt;
    [&amp;#039;أغسطس&amp;#039;]=8, [&amp;#039;اغسطس&amp;#039;]=8,&lt;br /&gt;
    [&amp;#039;سبتمبر&amp;#039;]=9, [&amp;#039;أكتوبر&amp;#039;]=10, [&amp;#039;اكتوبر&amp;#039;]=10,&lt;br /&gt;
    [&amp;#039;نوفمبر&amp;#039;]=11, [&amp;#039;ديسمبر&amp;#039;]=12,&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
local MONTH_OUT = {&lt;br /&gt;
    en = {&amp;#039;January&amp;#039;,&amp;#039;February&amp;#039;,&amp;#039;March&amp;#039;,&amp;#039;April&amp;#039;,&amp;#039;May&amp;#039;,&amp;#039;June&amp;#039;,&lt;br /&gt;
          &amp;#039;July&amp;#039;,&amp;#039;August&amp;#039;,&amp;#039;September&amp;#039;,&amp;#039;October&amp;#039;,&amp;#039;November&amp;#039;,&amp;#039;December&amp;#039;},&lt;br /&gt;
    ru = {&amp;#039;января&amp;#039;,&amp;#039;февраля&amp;#039;,&amp;#039;марта&amp;#039;,&amp;#039;апреля&amp;#039;,&amp;#039;мая&amp;#039;,&amp;#039;июня&amp;#039;,&lt;br /&gt;
          &amp;#039;июля&amp;#039;,&amp;#039;августа&amp;#039;,&amp;#039;сентября&amp;#039;,&amp;#039;октября&amp;#039;,&amp;#039;ноября&amp;#039;,&amp;#039;декабря&amp;#039;},&lt;br /&gt;
    ar = {&amp;#039;يناير&amp;#039;,&amp;#039;فبراير&amp;#039;,&amp;#039;مارس&amp;#039;,&amp;#039;أبريل&amp;#039;,&amp;#039;مايو&amp;#039;,&amp;#039;يونيو&amp;#039;,&lt;br /&gt;
          &amp;#039;يوليو&amp;#039;,&amp;#039;أغسطس&amp;#039;,&amp;#039;سبتمبر&amp;#039;,&amp;#039;أكتوبر&amp;#039;,&amp;#039;نوفمبر&amp;#039;,&amp;#039;ديسمبر&amp;#039;},&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
local function containsAny(s, list)&lt;br /&gt;
    for _, w in ipairs(list) do&lt;br /&gt;
        if mw.ustring.find(s, w, 1, true) then return true end&lt;br /&gt;
    end&lt;br /&gt;
    return false&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function findMonthDayByName(s)&lt;br /&gt;
    local lower_s = mw.ustring.lower(s)&lt;br /&gt;
    for name, num in pairs(MONTH_IN) do&lt;br /&gt;
        if mw.ustring.find(lower_s, name, 1, true) then&lt;br /&gt;
            local d = mw.ustring.match(lower_s, &amp;#039;(%d%d?)%s*&amp;#039; .. name)&lt;br /&gt;
            if not d then&lt;br /&gt;
                d = mw.ustring.match(lower_s, name .. &amp;#039;%s*(%d%d?)&amp;#039;)&lt;br /&gt;
            end&lt;br /&gt;
            if d then&lt;br /&gt;
                return num, tonumber(d)&lt;br /&gt;
            end&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
    return nil&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function normalize(s)&lt;br /&gt;
    s = tostring(s or &amp;#039;&amp;#039;)&lt;br /&gt;
    s = mw.ustring.gsub(s, &amp;#039;[?？]&amp;#039;, &amp;#039;&amp;#039;)&lt;br /&gt;
    s = mw.ustring.gsub(s, &amp;#039;[０-９]&amp;#039;, function(c)&lt;br /&gt;
        return string.char(string.byte(c) - 0xFEE0)&lt;br /&gt;
    end)&lt;br /&gt;
    local map = {&lt;br /&gt;
        [&amp;#039;٠&amp;#039;]=&amp;#039;0&amp;#039;,[&amp;#039;١&amp;#039;]=&amp;#039;1&amp;#039;,[&amp;#039;٢&amp;#039;]=&amp;#039;2&amp;#039;,[&amp;#039;٣&amp;#039;]=&amp;#039;3&amp;#039;,[&amp;#039;٤&amp;#039;]=&amp;#039;4&amp;#039;,&lt;br /&gt;
        [&amp;#039;٥&amp;#039;]=&amp;#039;5&amp;#039;,[&amp;#039;٦&amp;#039;]=&amp;#039;6&amp;#039;,[&amp;#039;٧&amp;#039;]=&amp;#039;7&amp;#039;,[&amp;#039;٨&amp;#039;]=&amp;#039;8&amp;#039;,[&amp;#039;٩&amp;#039;]=&amp;#039;9&amp;#039;,&lt;br /&gt;
        [&amp;#039;۰&amp;#039;]=&amp;#039;0&amp;#039;,[&amp;#039;۱&amp;#039;]=&amp;#039;1&amp;#039;,[&amp;#039;۲&amp;#039;]=&amp;#039;2&amp;#039;,[&amp;#039;۳&amp;#039;]=&amp;#039;3&amp;#039;,[&amp;#039;۴&amp;#039;]=&amp;#039;4&amp;#039;,&lt;br /&gt;
        [&amp;#039;۵&amp;#039;]=&amp;#039;5&amp;#039;,[&amp;#039;۶&amp;#039;]=&amp;#039;6&amp;#039;,[&amp;#039;۷&amp;#039;]=&amp;#039;7&amp;#039;,[&amp;#039;۸&amp;#039;]=&amp;#039;8&amp;#039;,[&amp;#039;۹&amp;#039;]=&amp;#039;9&amp;#039;,&lt;br /&gt;
    }&lt;br /&gt;
    s = mw.ustring.gsub(s, &amp;#039;[٠-٩۰-۹]&amp;#039;, function(c) return map[c] end)&lt;br /&gt;
    s = mw.ustring.gsub(s, &amp;#039;　&amp;#039;, &amp;#039; &amp;#039;)&lt;br /&gt;
    s = mw.ustring.gsub(s, &amp;#039;[ー－−―─—–~～〜]&amp;#039;, &amp;#039;-&amp;#039;)&lt;br /&gt;
    s = mw.ustring.lower(s)&lt;br /&gt;
    s = mw.ustring.gsub(s, &amp;#039;%s*から%s*&amp;#039;, &amp;#039;-&amp;#039;)&lt;br /&gt;
    s = mw.ustring.gsub(s, &amp;#039;%s*まで%s*&amp;#039;, &amp;#039;-&amp;#039;)&lt;br /&gt;
    s = mw.ustring.gsub(s, &amp;#039;%s*至%s*&amp;#039;, &amp;#039;-&amp;#039;)&lt;br /&gt;
    s = mw.ustring.gsub(s, &amp;#039;%s*到%s*&amp;#039;, &amp;#039;-&amp;#039;)&lt;br /&gt;
    s = mw.ustring.gsub(s, &amp;#039;%s*[Tt][Oo]%s*&amp;#039;, &amp;#039;-&amp;#039;)&lt;br /&gt;
    s = mw.ustring.gsub(s, &amp;#039;%s+по%s+&amp;#039;, &amp;#039;-&amp;#039;)&lt;br /&gt;
    s = mw.ustring.gsub(s, &amp;#039;%s*[Bb][Ii][Ss]%s+&amp;#039;, &amp;#039;-&amp;#039;)&lt;br /&gt;
    s = mw.ustring.gsub(s, &amp;#039;^%s*[Ff][Rr][Oo][Mm]%s+&amp;#039;, &amp;#039;&amp;#039;)&lt;br /&gt;
    s = mw.ustring.gsub(s, &amp;#039;^%s*[Bb][Oo][Rr][Nn]%s+(in%s+|on%s+)?&amp;#039;, &amp;#039;&amp;#039;)&lt;br /&gt;
    s = mw.ustring.gsub(s, &amp;#039;^%s*[Dd][Ii][Ee][Dd]%s+(in%s+|on%s+)?&amp;#039;, &amp;#039;&amp;#039;)&lt;br /&gt;
    s = mw.ustring.gsub(s, &amp;#039;^%s*[Dd][Ee]%s+&amp;#039;, &amp;#039;&amp;#039;)&lt;br /&gt;
    s = mw.ustring.gsub(s, &amp;#039;^%s*[Cc][Ii][Rr][Cc][Aa]%s+&amp;#039;, &amp;#039;&amp;#039;)&lt;br /&gt;
    s = mw.ustring.gsub(s, &amp;#039;^%s*[Cc][Aa]%.?%s+&amp;#039;, &amp;#039;&amp;#039;)&lt;br /&gt;
    s = mw.ustring.gsub(s, &amp;#039;^%s*с%s+&amp;#039;, &amp;#039;&amp;#039;)&lt;br /&gt;
    s = mw.ustring.gsub(s, &amp;#039;^%s*от%s+&amp;#039;, &amp;#039;&amp;#039;)&lt;br /&gt;
    return mw.text.trim(s)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function extractNumbers(s)&lt;br /&gt;
    local nums = {}&lt;br /&gt;
    for n in mw.ustring.gmatch(s, &amp;#039;%d+&amp;#039;) do&lt;br /&gt;
        table.insert(nums, tonumber(n))&lt;br /&gt;
    end&lt;br /&gt;
    return nums&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function isApproximate(s)&lt;br /&gt;
    if containsAny(s, APPROX) then return true end&lt;br /&gt;
    if mw.ustring.find(s, &amp;#039;-&amp;#039;, 1, true) then return true end&lt;br /&gt;
    return false&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- 元号（令和の終端は現在年）&lt;br /&gt;
local CURRENT_YEAR = tonumber(os.date(&amp;#039;%Y&amp;#039;)) or 2026&lt;br /&gt;
local ERAS = {&lt;br /&gt;
    {&amp;#039;明治&amp;#039;, 1868, 1912},&lt;br /&gt;
    {&amp;#039;大正&amp;#039;, 1912, 1926},&lt;br /&gt;
    {&amp;#039;昭和&amp;#039;, 1926, 1989},&lt;br /&gt;
    {&amp;#039;平成&amp;#039;, 1989, 2019},&lt;br /&gt;
    {&amp;#039;令和&amp;#039;, 2019, CURRENT_YEAR},&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
local function parseEra(s)&lt;br /&gt;
    for _, era in ipairs(ERAS) do&lt;br /&gt;
        local name, S, E = era[1], era[2], era[3]&lt;br /&gt;
        if mw.ustring.find(s, name, 1, true) then&lt;br /&gt;
            local L = E - S&lt;br /&gt;
            local n = tonumber(mw.ustring.match(s, &amp;#039;(%d+)年&amp;#039;))&lt;br /&gt;
            if n and n &amp;lt; 100 then&lt;br /&gt;
                return {year = S + n - 1, exact = false}&lt;br /&gt;
            end&lt;br /&gt;
            local dec = tonumber(mw.ustring.match(s, &amp;#039;(%d+)年代&amp;#039;))&lt;br /&gt;
            if dec and dec &amp;lt; 100 then&lt;br /&gt;
                return {year = S + dec - 1 + 5, exact = false}&lt;br /&gt;
            end&lt;br /&gt;
            if containsAny(s, {&amp;#039;末期&amp;#039;,&amp;#039;終期&amp;#039;,&amp;#039;晩期&amp;#039;,&amp;#039;最末期&amp;#039;}) then&lt;br /&gt;
                return {year = E - L/12, exact = false}&lt;br /&gt;
            end&lt;br /&gt;
            if containsAny(s, EARLY) then&lt;br /&gt;
                return {year = S + L/6, exact = false}&lt;br /&gt;
            end&lt;br /&gt;
            if containsAny(s, MID) then&lt;br /&gt;
                return {year = S + L/2, exact = false}&lt;br /&gt;
            end&lt;br /&gt;
            if containsAny(s, LATE) then&lt;br /&gt;
                return {year = S + 5*L/6, exact = false}&lt;br /&gt;
            end&lt;br /&gt;
            return {year = S + L/2, exact = false}&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
    return nil&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function parseYMD(s)&lt;br /&gt;
    local y1,m1,d1,y2,m2,d2 = mw.ustring.match(&lt;br /&gt;
        s, &amp;#039;(%d%d%d%d)年(%d%d?)月(%d%d?)日.-(%d%d%d%d)年(%d%d?)月(%d%d?)日&amp;#039;)&lt;br /&gt;
    if y1 then&lt;br /&gt;
        return {year=(tonumber(y1)+tonumber(y2))/2,&lt;br /&gt;
                month=(tonumber(m1)+tonumber(m2))/2,&lt;br /&gt;
                day=(tonumber(d1)+tonumber(d2))/2, exact=false}&lt;br /&gt;
    end&lt;br /&gt;
    local y3,m3,d3,d4 = mw.ustring.match(&lt;br /&gt;
        s, &amp;#039;(%d%d%d%d)年(%d%d?)月(%d%d?)日.-(%d%d?)日&amp;#039;)&lt;br /&gt;
    if y3 then&lt;br /&gt;
        return {year=tonumber(y3), month=tonumber(m3),&lt;br /&gt;
                day=(tonumber(d3)+tonumber(d4))/2, exact=false}&lt;br /&gt;
    end&lt;br /&gt;
    local y4,m4,d4b = mw.ustring.match(s, &amp;#039;(%d%d%d%d)年(%d%d?)月(%d%d?)日&amp;#039;)&lt;br /&gt;
    if y4 then return {year=tonumber(y4),month=tonumber(m4),day=tonumber(d4b),exact=true} end&lt;br /&gt;
    local yk1,mk1,dk1,yk2,mk2,dk2 = mw.ustring.match(&lt;br /&gt;
        s, &amp;#039;(%d%d%d%d)년%s*(%d%d?)월%s*(%d%d?)일.-(%d%d%d%d)년%s*(%d%d?)월%s*(%d%d?)일&amp;#039;)&lt;br /&gt;
    if yk1 then&lt;br /&gt;
        return {year=(tonumber(yk1)+tonumber(yk2))/2,&lt;br /&gt;
                month=(tonumber(mk1)+tonumber(mk2))/2,&lt;br /&gt;
                day=(tonumber(dk1)+tonumber(dk2))/2, exact=false}&lt;br /&gt;
    end&lt;br /&gt;
    local yk,mk,dk = mw.ustring.match(s, &amp;#039;(%d%d%d%d)년%s*(%d%d?)월%s*(%d%d?)일&amp;#039;)&lt;br /&gt;
    if yk then return {year=tonumber(yk),month=tonumber(mk),day=tonumber(dk),exact=true} end&lt;br /&gt;
    local ya, ma, da = mw.ustring.match(s, &amp;#039;(%d%d%d%d)[%-/%.](%d%d?)[%-/%.](%d%d?)&amp;#039;)&lt;br /&gt;
    if ya then return {year=tonumber(ya),month=tonumber(ma),day=tonumber(da),exact=true} end&lt;br /&gt;
    local y_named = tonumber(mw.ustring.match(s, &amp;#039;(%d%d%d%d)&amp;#039;))&lt;br /&gt;
    if y_named then&lt;br /&gt;
        local mn, dd = findMonthDayByName(s)&lt;br /&gt;
        if mn and dd then&lt;br /&gt;
            return {year=y_named, month=mn, day=dd, exact=true}&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
    local y5,m5 = mw.ustring.match(s, &amp;#039;(%d%d%d%d)年(%d%d?)月&amp;#039;)&lt;br /&gt;
    if y5 then return {year=tonumber(y5),month=tonumber(m5),day=15,exact=false} end&lt;br /&gt;
    local y5k,m5k = mw.ustring.match(s, &amp;#039;(%d%d%d%d)년%s*(%d%d?)월&amp;#039;)&lt;br /&gt;
    if y5k then return {year=tonumber(y5k),month=tonumber(m5k),day=15,exact=false} end&lt;br /&gt;
    local y6 = tonumber(mw.ustring.match(s, &amp;#039;(%d%d%d%d)年&amp;#039;))&lt;br /&gt;
    if y6 then&lt;br /&gt;
        if containsAny(s, {&amp;#039;上半期&amp;#039;,&amp;#039;上期&amp;#039;,&amp;#039;上半年&amp;#039;,&amp;#039;上半&amp;#039;,&amp;#039;상반기&amp;#039;,&lt;br /&gt;
                           &amp;#039;первая&amp;#039;,&amp;#039;первой&amp;#039;,&amp;#039;first half&amp;#039;,&amp;#039;1st half&amp;#039;,&amp;#039;النصف الأول&amp;#039;}) then&lt;br /&gt;
            return {year=y6,month=3,day=15,exact=false}&lt;br /&gt;
        end&lt;br /&gt;
        if containsAny(s, {&amp;#039;下半期&amp;#039;,&amp;#039;下期&amp;#039;,&amp;#039;下半年&amp;#039;,&amp;#039;下半&amp;#039;,&amp;#039;하반기&amp;#039;,&lt;br /&gt;
                           &amp;#039;вторая&amp;#039;,&amp;#039;второй&amp;#039;,&amp;#039;second half&amp;#039;,&amp;#039;2nd half&amp;#039;,&amp;#039;النصف الثاني&amp;#039;}) then&lt;br /&gt;
            return {year=y6,month=9,day=15,exact=false}&lt;br /&gt;
        end&lt;br /&gt;
        return {year=y6,exact=true}&lt;br /&gt;
    end&lt;br /&gt;
    local y6k = tonumber(mw.ustring.match(s, &amp;#039;(%d%d%d%d)년&amp;#039;))&lt;br /&gt;
    if y6k then&lt;br /&gt;
        if containsAny(s, {&amp;#039;상반기&amp;#039;}) then&lt;br /&gt;
            return {year=y6k,month=3,day=15,exact=false}&lt;br /&gt;
        end&lt;br /&gt;
        if containsAny(s, {&amp;#039;하반기&amp;#039;}) then&lt;br /&gt;
            return {year=y6k,month=9,day=15,exact=false}&lt;br /&gt;
        end&lt;br /&gt;
        return {year=y6k,exact=true}&lt;br /&gt;
    end&lt;br /&gt;
    return nil&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function parseDecade(s, nums)&lt;br /&gt;
    local era = parseEra(s)&lt;br /&gt;
    if era then return era end&lt;br /&gt;
&lt;br /&gt;
    if #nums == 0 then return nil end&lt;br /&gt;
    local off = 5&lt;br /&gt;
    if containsAny(s, EARLY) then off = 2&lt;br /&gt;
    elseif containsAny(s, MID) then off = 5&lt;br /&gt;
    elseif containsAny(s, LATE)  then off = 7 end&lt;br /&gt;
&lt;br /&gt;
    local base4 = mw.ustring.match(s, &amp;#039;(%d%d%d%d)s&amp;#039;)&lt;br /&gt;
    if base4 then return {year = tonumber(base4) + off, exact = false} end&lt;br /&gt;
    local base2 = mw.ustring.match(s, &amp;#039;(%d%d)s&amp;#039;)&lt;br /&gt;
    if base2 then return {age = tonumber(base2) + off, exact = false} end&lt;br /&gt;
&lt;br /&gt;
    local nendai = mw.ustring.find(s, &amp;#039;年代&amp;#039;, 1, true)&lt;br /&gt;
                or mw.ustring.find(s, &amp;#039;년대&amp;#039;, 1, true)&lt;br /&gt;
    local dai = mw.ustring.find(s, &amp;#039;代&amp;#039;, 1, true)&lt;br /&gt;
             or mw.ustring.find(s, &amp;#039;台&amp;#039;, 1, true)&lt;br /&gt;
             or mw.ustring.find(s, &amp;#039;대&amp;#039;, 1, true)&lt;br /&gt;
&lt;br /&gt;
    if nendai then&lt;br /&gt;
        local base = nums[1]&lt;br /&gt;
        if base &amp;lt; 100 then base = base + 1900 end&lt;br /&gt;
        return {year = base + off, exact = false}&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    local ru = mw.ustring.match(s, &amp;#039;(%d%d%d%d)[%-]?[ех]&amp;#039;)&lt;br /&gt;
    if ru then return {year = tonumber(ru) + off, exact = false} end&lt;br /&gt;
&lt;br /&gt;
    if dai then&lt;br /&gt;
        local base = nums[1]&lt;br /&gt;
        if base &amp;gt;= 1900 then return {year = base + off, exact = false} end&lt;br /&gt;
        if base &amp;lt; 100 then return {age = base + off, exact = false} end&lt;br /&gt;
    end&lt;br /&gt;
    return nil&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function parseAge(s, nums)&lt;br /&gt;
    local markers = {&amp;#039;歳&amp;#039;,&amp;#039;才&amp;#039;,&amp;#039;살&amp;#039;,&amp;#039;세&amp;#039;,&amp;#039;years old&amp;#039;,&amp;#039;year old&amp;#039;,&amp;#039;y.o.&amp;#039;,&amp;#039;yo.&amp;#039;,&lt;br /&gt;
                     &amp;#039; سنة&amp;#039;,&amp;#039;سنةً&amp;#039;,&amp;#039;عاما&amp;#039;,&amp;#039;عاماً&amp;#039;,&amp;#039;عام&amp;#039;}&lt;br /&gt;
    local found = false&lt;br /&gt;
    for _, m in ipairs(markers) do&lt;br /&gt;
        if mw.ustring.find(s, m, 1, true) then found = true; break end&lt;br /&gt;
    end&lt;br /&gt;
    if not found then return nil end&lt;br /&gt;
    if #nums == 0 then return nil end&lt;br /&gt;
    if #nums &amp;gt;= 2 then&lt;br /&gt;
        local a,b = nums[1],nums[2]&lt;br /&gt;
        if a&amp;gt;b then a,b = b,a end&lt;br /&gt;
        return {age=(a+b)/2, exact=false}&lt;br /&gt;
    end&lt;br /&gt;
    local a = nums[1]&lt;br /&gt;
    if mw.ustring.find(s, &amp;#039;弱&amp;#039;, 1, true) then a = a - 1 end&lt;br /&gt;
    if mw.ustring.find(s, &amp;#039;強&amp;#039;, 1, true) then a = a + 1 end&lt;br /&gt;
    return {age=a, exact=not isApproximate(s)}&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function parseExpression(s)&lt;br /&gt;
    s = normalize(s)&lt;br /&gt;
    if s == &amp;#039;&amp;#039; then return nil end&lt;br /&gt;
    local nums = extractNumbers(s)&lt;br /&gt;
    if #nums == 0 and not mw.ustring.find(s, &amp;#039;昭和&amp;#039;, 1, true)&lt;br /&gt;
       and not mw.ustring.find(s, &amp;#039;平成&amp;#039;, 1, true)&lt;br /&gt;
       and not mw.ustring.find(s, &amp;#039;大正&amp;#039;, 1, true)&lt;br /&gt;
       and not mw.ustring.find(s, &amp;#039;明治&amp;#039;, 1, true)&lt;br /&gt;
       and not mw.ustring.find(s, &amp;#039;令和&amp;#039;, 1, true) then&lt;br /&gt;
        return nil&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    local dec = parseDecade(s, nums); if dec then return dec end&lt;br /&gt;
    local age = parseAge(s, nums);    if age then return age end&lt;br /&gt;
    local ymd = parseYMD(s);          if ymd then return ymd end&lt;br /&gt;
&lt;br /&gt;
    if #nums &amp;gt;= 2 then&lt;br /&gt;
        local a,b = nums[1], nums[2]&lt;br /&gt;
        if a &amp;gt;= 1000 and a &amp;lt;= 2200 and b &amp;lt; 100 then&lt;br /&gt;
            local mult = 10 ^ #tostring(b)&lt;br /&gt;
            b = math.floor(a / mult) * mult + b&lt;br /&gt;
        end&lt;br /&gt;
        if a &amp;gt; b then a,b = b,a end&lt;br /&gt;
        if a &amp;gt;= 1000 and b &amp;lt;= 2200 then&lt;br /&gt;
            return {year=(a+b)/2, exact=false}&lt;br /&gt;
        else&lt;br /&gt;
            return {age=(a+b)/2,  exact=false}&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
    local n = nums[1]&lt;br /&gt;
    if n &amp;gt;= 1000 and n &amp;lt;= 2200 then&lt;br /&gt;
        return {year=n, exact=not isApproximate(s)}&lt;br /&gt;
    else&lt;br /&gt;
        return {age=n,  exact=not isApproximate(s)}&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- 月日のみを抽出（年なし）&lt;br /&gt;
local function parseMonthDay(s)&lt;br /&gt;
    if s == &amp;#039;&amp;#039; then return nil end&lt;br /&gt;
    local bm, bd = mw.ustring.match(s, &amp;#039;(%d%d?)月(%d%d?)日&amp;#039;)&lt;br /&gt;
    if bm and bd then&lt;br /&gt;
        return {month=tonumber(bm), day=tonumber(bd), exact=true}&lt;br /&gt;
    end&lt;br /&gt;
    bm, bd = mw.ustring.match(s, &amp;#039;(%d%d?)월%s*(%d%d?)일&amp;#039;)&lt;br /&gt;
    if bm and bd then&lt;br /&gt;
        return {month=tonumber(bm), day=tonumber(bd), exact=true}&lt;br /&gt;
    end&lt;br /&gt;
    bm = mw.ustring.match(s, &amp;#039;(%d%d?)月&amp;#039;)&lt;br /&gt;
    if bm then&lt;br /&gt;
        return {month=tonumber(bm), day=15, exact=false}&lt;br /&gt;
    end&lt;br /&gt;
    bm = mw.ustring.match(s, &amp;#039;(%d%d?)월&amp;#039;)&lt;br /&gt;
    if bm then&lt;br /&gt;
        return {month=tonumber(bm), day=15, exact=false}&lt;br /&gt;
    end&lt;br /&gt;
    local mn, dd = findMonthDayByName(s)&lt;br /&gt;
    if mn and dd then&lt;br /&gt;
        return {month=mn, day=dd, exact=true}&lt;br /&gt;
    end&lt;br /&gt;
    local nm, nd = mw.ustring.match(s, &amp;#039;^(%d%d?)[%-/%.](%d%d?)$&amp;#039;)&lt;br /&gt;
    if nm and nd then&lt;br /&gt;
        return {month=tonumber(nm), day=tonumber(nd), exact=true}&lt;br /&gt;
    end&lt;br /&gt;
    return nil&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- 生年の末尾に付いた「年」「년」を数値のみの場合に限って除去&lt;br /&gt;
local function stripYearSuffix(s)&lt;br /&gt;
    s = trim(s)&lt;br /&gt;
    if s == &amp;#039;&amp;#039; then return s end&lt;br /&gt;
    local n = mw.ustring.match(s, &amp;#039;^(%d+)年$&amp;#039;) or mw.ustring.match(s, &amp;#039;^(%d+)년$&amp;#039;)&lt;br /&gt;
    if n then return n end&lt;br /&gt;
    return s&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function parseBirth(birth, birth2)&lt;br /&gt;
    birth = stripYearSuffix(birth)&lt;br /&gt;
&lt;br /&gt;
    if birth ~= &amp;#039;&amp;#039; and birth2 == &amp;#039;&amp;#039; then&lt;br /&gt;
        return parseExpression(birth)&lt;br /&gt;
    end&lt;br /&gt;
    if birth == &amp;#039;&amp;#039; and birth2 ~= &amp;#039;&amp;#039; then&lt;br /&gt;
        return parseMonthDay(birth2)&lt;br /&gt;
    end&lt;br /&gt;
    if birth ~= &amp;#039;&amp;#039; and birth2 ~= &amp;#039;&amp;#039; then&lt;br /&gt;
        local by = tonumber(birth)&lt;br /&gt;
        if by and by &amp;gt;= 1000 and by &amp;lt;= 2200 then&lt;br /&gt;
            local bm, bd = mw.ustring.match(birth2, &amp;#039;(%d%d?)月(%d%d?)日&amp;#039;)&lt;br /&gt;
            if bm and bd then&lt;br /&gt;
                return {year=by, month=tonumber(bm), day=tonumber(bd), exact=true}&lt;br /&gt;
            end&lt;br /&gt;
            bm, bd = mw.ustring.match(birth2, &amp;#039;(%d%d?)월%s*(%d%d?)일&amp;#039;)&lt;br /&gt;
            if bm and bd then&lt;br /&gt;
                return {year=by, month=tonumber(bm), day=tonumber(bd), exact=true}&lt;br /&gt;
            end&lt;br /&gt;
            local bm2 = mw.ustring.match(birth2, &amp;#039;(%d%d?)月&amp;#039;)&lt;br /&gt;
            if bm2 then&lt;br /&gt;
                return {year=by, month=tonumber(bm2), day=15, exact=false}&lt;br /&gt;
            end&lt;br /&gt;
            bm2 = mw.ustring.match(birth2, &amp;#039;(%d%d?)월&amp;#039;)&lt;br /&gt;
            if bm2 then&lt;br /&gt;
                return {year=by, month=tonumber(bm2), day=15, exact=false}&lt;br /&gt;
            end&lt;br /&gt;
            local mn, dd = findMonthDayByName(birth2)&lt;br /&gt;
            if mn and dd then&lt;br /&gt;
                return {year=by, month=mn, day=dd, exact=true}&lt;br /&gt;
            end&lt;br /&gt;
            local nm, nd = mw.ustring.match(birth2, &amp;#039;^(%d%d?)[%-/%.](%d%d?)$&amp;#039;)&lt;br /&gt;
            if nm and nd then&lt;br /&gt;
                return {year=by, month=tonumber(nm), day=tonumber(nd), exact=true}&lt;br /&gt;
            end&lt;br /&gt;
        end&lt;br /&gt;
        local combined&lt;br /&gt;
        if mw.ustring.find(birth2,&amp;#039;月&amp;#039;) or mw.ustring.find(birth2,&amp;#039;日&amp;#039;)&lt;br /&gt;
           or mw.ustring.find(birth2,&amp;#039;월&amp;#039;) or mw.ustring.find(birth2,&amp;#039;일&amp;#039;) then&lt;br /&gt;
            combined = birth .. &amp;#039;年&amp;#039; .. birth2&lt;br /&gt;
        else&lt;br /&gt;
            combined = birth .. birth2&lt;br /&gt;
        end&lt;br /&gt;
        return parseExpression(combined)&lt;br /&gt;
    end&lt;br /&gt;
    return nil&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function units(lang)&lt;br /&gt;
    if lang==&amp;#039;en&amp;#039;      then return &amp;#039; years old&amp;#039;,&amp;#039; approx.&amp;#039; end&lt;br /&gt;
    if lang==&amp;#039;ar&amp;#039;      then return &amp;#039; سنة&amp;#039;,&amp;#039; حوالي&amp;#039; end&lt;br /&gt;
    if lang==&amp;#039;zh&amp;#039;      then return &amp;#039;岁&amp;#039;,&amp;#039;左右&amp;#039; end&lt;br /&gt;
    if lang==&amp;#039;zh-hant&amp;#039; then return &amp;#039;歲&amp;#039;,&amp;#039;左右&amp;#039; end&lt;br /&gt;
    if lang==&amp;#039;ko&amp;#039;      then return &amp;#039;살&amp;#039;,&amp;#039;경&amp;#039; end&lt;br /&gt;
    if lang==&amp;#039;ru&amp;#039;      then return &amp;#039; лет&amp;#039;,&amp;#039; ок.&amp;#039; end&lt;br /&gt;
    return &amp;#039;歳&amp;#039;,&amp;#039;頃&amp;#039;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function formatBirthDate(lang, y, m, d)&lt;br /&gt;
    if m and d then&lt;br /&gt;
        if lang==&amp;#039;ko&amp;#039; then&lt;br /&gt;
            return string.format(&amp;#039;%d년 %d월 %d일&amp;#039;, y, m, d)&lt;br /&gt;
        elseif lang==&amp;#039;en&amp;#039; then&lt;br /&gt;
            return MONTH_OUT.en[m] .. &amp;#039; &amp;#039; .. d .. &amp;#039;, &amp;#039; .. y&lt;br /&gt;
        elseif lang==&amp;#039;ru&amp;#039; then&lt;br /&gt;
            return d .. &amp;#039; &amp;#039; .. MONTH_OUT.ru[m] .. &amp;#039; &amp;#039; .. y&lt;br /&gt;
        elseif lang==&amp;#039;ar&amp;#039; then&lt;br /&gt;
            return d .. &amp;#039; &amp;#039; .. MONTH_OUT.ar[m] .. &amp;#039; &amp;#039; .. y&lt;br /&gt;
        else&lt;br /&gt;
            return string.format(&amp;#039;%d年%d月%d日&amp;#039;, y, m, d)&lt;br /&gt;
        end&lt;br /&gt;
    else&lt;br /&gt;
        if lang==&amp;#039;ko&amp;#039; then&lt;br /&gt;
            return tostring(y) .. &amp;#039;년&amp;#039;&lt;br /&gt;
        elseif lang==&amp;#039;en&amp;#039; or lang==&amp;#039;ru&amp;#039; or lang==&amp;#039;ar&amp;#039; then&lt;br /&gt;
            return tostring(y)&lt;br /&gt;
        else&lt;br /&gt;
            return tostring(y) .. &amp;#039;年&amp;#039;&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function formatMonthDay(lang, m, d)&lt;br /&gt;
    if lang==&amp;#039;ko&amp;#039; then&lt;br /&gt;
        return string.format(&amp;#039;%d월 %d일&amp;#039;, m, d)&lt;br /&gt;
    elseif lang==&amp;#039;en&amp;#039; then&lt;br /&gt;
        return MONTH_OUT.en[m] .. &amp;#039; &amp;#039; .. d&lt;br /&gt;
    elseif lang==&amp;#039;ru&amp;#039; then&lt;br /&gt;
        return d .. &amp;#039; &amp;#039; .. MONTH_OUT.ru[m]&lt;br /&gt;
    elseif lang==&amp;#039;ar&amp;#039; then&lt;br /&gt;
        return d .. &amp;#039; &amp;#039; .. MONTH_OUT.ar[m]&lt;br /&gt;
    else&lt;br /&gt;
        return string.format(&amp;#039;%d月%d日&amp;#039;, m, d)&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.field(frame)&lt;br /&gt;
    local args = frame:getParent().args&lt;br /&gt;
    local ageStr = trim(args[&amp;#039;年齢&amp;#039;])&lt;br /&gt;
    local birth  = trim(args[&amp;#039;生年&amp;#039;])&lt;br /&gt;
    local birth2 = trim(args[&amp;#039;生年2&amp;#039;])&lt;br /&gt;
    local lang   = trim(args[&amp;#039;lang&amp;#039;]); if lang==&amp;#039;&amp;#039; then lang=&amp;#039;ja&amp;#039; end&lt;br /&gt;
    lang = mw.ustring.lower(lang)&lt;br /&gt;
&lt;br /&gt;
    local ageInfo   = (ageStr ~= &amp;#039;&amp;#039;) and parseExpression(ageStr) or nil&lt;br /&gt;
    local birthInfo = parseBirth(birth, birth2)&lt;br /&gt;
&lt;br /&gt;
    local refY = tonumber(os.date(&amp;#039;%Y&amp;#039;))&lt;br /&gt;
    local refM = tonumber(os.date(&amp;#039;%m&amp;#039;))&lt;br /&gt;
    local refD = tonumber(os.date(&amp;#039;%d&amp;#039;))&lt;br /&gt;
&lt;br /&gt;
    local finalAge, ageApprox, ageRange = nil, false, nil&lt;br /&gt;
    local src = ageInfo or birthInfo&lt;br /&gt;
    if src then&lt;br /&gt;
        if src.age then&lt;br /&gt;
            finalAge = src.age&lt;br /&gt;
            ageApprox = not src.exact&lt;br /&gt;
        elseif src.year then&lt;br /&gt;
            finalAge = refY - src.year&lt;br /&gt;
            if src.month and src.day then&lt;br /&gt;
                if refM &amp;lt; src.month or (refM == src.month and refD &amp;lt; src.day) then&lt;br /&gt;
                    finalAge = finalAge - 1&lt;br /&gt;
                end&lt;br /&gt;
            end&lt;br /&gt;
            ageApprox = not src.exact&lt;br /&gt;
            if lang==&amp;#039;ja&amp;#039; and not ageInfo and src.exact&lt;br /&gt;
               and not src.month and src.year then&lt;br /&gt;
                local y = math.floor(src.year + 0.5)&lt;br /&gt;
                local mx = refY - y&lt;br /&gt;
                ageRange = {min=mx-1, max=mx}&lt;br /&gt;
            end&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    local ageUnit, approxMark = units(lang)&lt;br /&gt;
&lt;br /&gt;
    local birthOut = &amp;#039;&amp;#039;&lt;br /&gt;
    if birthInfo then&lt;br /&gt;
        if birthInfo.year then&lt;br /&gt;
            local by = math.floor(birthInfo.year + 0.5)&lt;br /&gt;
            local bm = birthInfo.month and math.floor(birthInfo.month + 0.5) or nil&lt;br /&gt;
            local bd = birthInfo.day   and math.floor(birthInfo.day   + 0.5) or nil&lt;br /&gt;
            birthOut = formatBirthDate(lang, by, bm, bd)&lt;br /&gt;
        elseif birthInfo.month and birthInfo.day then&lt;br /&gt;
            local bm = math.floor(birthInfo.month + 0.5)&lt;br /&gt;
            local bd = math.floor(birthInfo.day + 0.5)&lt;br /&gt;
            birthOut = formatMonthDay(lang, bm, bd)&lt;br /&gt;
        end&lt;br /&gt;
        if birthOut ~= &amp;#039;&amp;#039; and not birthInfo.exact then&lt;br /&gt;
            birthOut = birthOut .. approxMark&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    if birth ~= &amp;#039;&amp;#039; and birth2 ~= &amp;#039;&amp;#039; and birthInfo and birthInfo.exact&lt;br /&gt;
       and not birthInfo.month then&lt;br /&gt;
        if lang==&amp;#039;en&amp;#039; or lang==&amp;#039;ar&amp;#039; or lang==&amp;#039;ru&amp;#039; then&lt;br /&gt;
            birthOut = birth2 .. &amp;#039;, &amp;#039; .. birth&lt;br /&gt;
        elseif lang==&amp;#039;ja&amp;#039; or lang==&amp;#039;zh&amp;#039; or lang==&amp;#039;zh-hant&amp;#039; then&lt;br /&gt;
            birthOut = birth .. &amp;#039;年&amp;#039; .. birth2&lt;br /&gt;
        elseif lang==&amp;#039;ko&amp;#039; then&lt;br /&gt;
            birthOut = birth .. &amp;#039;년 &amp;#039; .. birth2&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    if birthOut == &amp;#039;&amp;#039; and finalAge then&lt;br /&gt;
        local by = math.floor(refY - finalAge + 0.5)&lt;br /&gt;
        if lang==&amp;#039;en&amp;#039; or lang==&amp;#039;ru&amp;#039; or lang==&amp;#039;ar&amp;#039; then&lt;br /&gt;
            birthOut = tostring(by)&lt;br /&gt;
        elseif lang==&amp;#039;ko&amp;#039; then&lt;br /&gt;
            birthOut = tostring(by) .. &amp;#039;년&amp;#039;&lt;br /&gt;
        else&lt;br /&gt;
            birthOut = tostring(by) .. &amp;#039;年&amp;#039;&lt;br /&gt;
        end&lt;br /&gt;
        birthOut = birthOut .. approxMark&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    local ageOut = &amp;#039;&amp;#039;&lt;br /&gt;
    if ageRange then&lt;br /&gt;
        ageOut = tostring(ageRange.min)..&amp;#039;～&amp;#039;..tostring(ageRange.max)..ageUnit&lt;br /&gt;
    elseif finalAge then&lt;br /&gt;
        local a = math.floor(finalAge + 0.5)&lt;br /&gt;
        ageOut = tostring(a)..ageUnit&lt;br /&gt;
        if ageApprox then ageOut = ageOut .. approxMark end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    if ageInfo == nil and ageStr ~= &amp;#039;&amp;#039; and not isPlaceholder(ageStr) then&lt;br /&gt;
        ageOut = ageStr&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    if birthInfo == nil and (birth ~= &amp;#039;&amp;#039; or birth2 ~= &amp;#039;&amp;#039;) then&lt;br /&gt;
        local combined&lt;br /&gt;
        if birth ~= &amp;#039;&amp;#039; and birth2 ~= &amp;#039;&amp;#039; then&lt;br /&gt;
            combined = birth .. &amp;#039; &amp;#039; .. birth2&lt;br /&gt;
        elseif birth ~= &amp;#039;&amp;#039; then&lt;br /&gt;
            combined = birth&lt;br /&gt;
        else&lt;br /&gt;
            combined = birth2&lt;br /&gt;
        end&lt;br /&gt;
        if not isPlaceholder(combined) then&lt;br /&gt;
            birthOut = combined&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    if lang==&amp;#039;en&amp;#039; then&lt;br /&gt;
        if ageOut~=&amp;#039;&amp;#039; and birthOut~=&amp;#039;&amp;#039; then return ageOut..&amp;#039;, born &amp;#039;..birthOut end&lt;br /&gt;
        if ageOut~=&amp;#039;&amp;#039; then return ageOut end&lt;br /&gt;
        if birthOut~=&amp;#039;&amp;#039; then return &amp;#039;born &amp;#039;..birthOut end&lt;br /&gt;
    elseif lang==&amp;#039;ar&amp;#039; then&lt;br /&gt;
        if ageOut~=&amp;#039;&amp;#039; and birthOut~=&amp;#039;&amp;#039; then return ageOut..&amp;#039;، ولد في &amp;#039;..birthOut end&lt;br /&gt;
        if ageOut~=&amp;#039;&amp;#039; then return ageOut end&lt;br /&gt;
        if birthOut~=&amp;#039;&amp;#039; then return &amp;#039;ولد في &amp;#039;..birthOut end&lt;br /&gt;
    elseif lang==&amp;#039;zh&amp;#039; or lang==&amp;#039;zh-hant&amp;#039; then&lt;br /&gt;
        if ageOut~=&amp;#039;&amp;#039; and birthOut~=&amp;#039;&amp;#039; then return ageOut..&amp;#039;，&amp;#039;..birthOut..&amp;#039;生&amp;#039; end&lt;br /&gt;
        if ageOut~=&amp;#039;&amp;#039; then return ageOut end&lt;br /&gt;
        if birthOut~=&amp;#039;&amp;#039; then return birthOut..&amp;#039;生&amp;#039; end&lt;br /&gt;
    elseif lang==&amp;#039;ko&amp;#039; then&lt;br /&gt;
        if ageOut~=&amp;#039;&amp;#039; and birthOut~=&amp;#039;&amp;#039; then return ageOut..&amp;#039;, &amp;#039;..birthOut..&amp;#039;생&amp;#039; end&lt;br /&gt;
        if ageOut~=&amp;#039;&amp;#039; then return ageOut end&lt;br /&gt;
        if birthOut~=&amp;#039;&amp;#039; then return birthOut..&amp;#039;생&amp;#039; end&lt;br /&gt;
    elseif lang==&amp;#039;ru&amp;#039; then&lt;br /&gt;
        if ageOut~=&amp;#039;&amp;#039; and birthOut~=&amp;#039;&amp;#039; then return ageOut..&amp;#039;, род. &amp;#039;..birthOut end&lt;br /&gt;
        if ageOut~=&amp;#039;&amp;#039; then return ageOut end&lt;br /&gt;
        if birthOut~=&amp;#039;&amp;#039; then return &amp;#039;род. &amp;#039;..birthOut end&lt;br /&gt;
    else&lt;br /&gt;
        if ageOut~=&amp;#039;&amp;#039; and birthOut~=&amp;#039;&amp;#039; then return ageOut..&amp;#039;、&amp;#039;..birthOut..&amp;#039;生まれ&amp;#039; end&lt;br /&gt;
        if ageOut~=&amp;#039;&amp;#039; then return ageOut end&lt;br /&gt;
        if birthOut~=&amp;#039;&amp;#039; then return birthOut..&amp;#039;生まれ&amp;#039; end&lt;br /&gt;
    end&lt;br /&gt;
    return &amp;#039;&amp;#039;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.hasdata(frame)&lt;br /&gt;
    local args = frame:getParent().args&lt;br /&gt;
    local ageStr = trim(args[&amp;#039;年齢&amp;#039;])&lt;br /&gt;
    local birth  = trim(args[&amp;#039;生年&amp;#039;])&lt;br /&gt;
    local birth2 = trim(args[&amp;#039;生年2&amp;#039;])&lt;br /&gt;
&lt;br /&gt;
    if ageStr ~= &amp;#039;&amp;#039; and not isPlaceholder(ageStr) then return &amp;#039;x&amp;#039; end&lt;br /&gt;
    if birth ~= &amp;#039;&amp;#039; and not isPlaceholder(birth) then return &amp;#039;x&amp;#039; end&lt;br /&gt;
    if birth2 ~= &amp;#039;&amp;#039; and not isPlaceholder(birth2) then return &amp;#039;x&amp;#039; end&lt;br /&gt;
    return &amp;#039;&amp;#039;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
return p&lt;/div&gt;</summary>
		<author><name>エーデルメーア</name></author>
	</entry>
</feed>