Module:Age: Difference between revisions
update from sandbox: implement Template:Death date and age
(update from sandbox: prefix=TEXT inserts TEXT before visible result but after any sort key, with space appended to TEXT if it is more than one character) |
(update from sandbox: implement Template:Death date and age) |
||
Line 499: | Line 499: | ||
-- Don't bother detecting if wantMixture is used because not needed and it is a poor option. | -- Don't bother detecting if wantMixture is used because not needed and it is a poor option. | ||
if not text then | if not text then | ||
if getopt.noMissing then | |||
return nil -- this gives a nil date which gives an error | |||
end | |||
text = 'currentdate' | text = 'currentdate' | ||
if getopt.flag == 'usesCurrent' then | if getopt.flag == 'usesCurrent' then | ||
Line 537: | Line 540: | ||
end | end | ||
local fix = getopt.fix and 'fix' or '' | local fix = getopt.fix and 'fix' or '' | ||
local partialText = getopt.partial and 'partial' or '' | local partialText = getopt.partial and 'partial' or '' | ||
local dates = {} | local dates = {} | ||
Line 563: | Line 565: | ||
if (getopt.partial and y and (m or not d)) or (y and m and d) then | if (getopt.partial and y and (m or not d)) or (y and m and d) then | ||
dates[i] = Date(fix, partialText, y, m, d) | dates[i] = Date(fix, partialText, y, m, d) | ||
elseif not y and not m and not d | elseif not y and not m and not d then | ||
dates[i] = Date(flagCurrent()) | dates[i] = Date(flagCurrent()) | ||
end | end | ||
end | end | ||
end | end | ||
else | |||
getopt.textdates = true -- have parsed each date from a single text field | getopt.textdates = true -- have parsed each date from a single text field | ||
dates[1] = Date(fix, partialText, flagCurrent(fields[1])) | dates[1] = Date(fix, partialText, flagCurrent(fields[1])) | ||
Line 576: | Line 578: | ||
end | end | ||
if not dates[1] then | if not dates[1] then | ||
return message('Need valid year, month, day') | return message(getopt.missing1 or 'Need valid year, month, day') | ||
end | end | ||
if getopt.single then | if getopt.single then | ||
Line 582: | Line 584: | ||
end | end | ||
if not dates[2] then | if not dates[2] then | ||
return message('Second date should be year, month, day') | return message(getopt.missing2 or 'Second date should be year, month, day') | ||
end | end | ||
return dates[1], dates[2] | return dates[1], dates[2] | ||
Line 762: | Line 764: | ||
-- Implement [[Template:Birth date and age]]. | -- Implement [[Template:Birth date and age]]. | ||
local args = frame:getParent().args | local args = frame:getParent().args | ||
local options = { noMissing=true, single=true } | local options = { | ||
missing1 = 'Need valid birth date: year, month, day', | |||
noMissing = true, | |||
single = true, | |||
} | |||
local date = getDates(frame, options) | local date = getDates(frame, options) | ||
if type(date) == 'string' then | if type(date) == 'string' then | ||
Line 812: | Line 818: | ||
local invalid | local invalid | ||
local imax = options.textdates and 1 or 3 | local imax = options.textdates and 1 or 3 | ||
for k, _ in pairs(args) do | |||
if type(k) == 'number' then | |||
if k > imax then | |||
invalid = tostring(k) | |||
break | |||
end | |||
else | |||
if not good[k] then | |||
invalid = k | |||
break | |||
end | |||
end | |||
end | |||
if invalid then | |||
result = result .. message('invalid parameter ' .. invalid, 'warning') | |||
end | |||
end | |||
return result | |||
end | |||
local function dda(frame) | |||
-- Implement [[Template:Death date and age]]. | |||
local args = frame:getParent().args | |||
local options = { | |||
missing1 = 'Need valid death date (first date): year, month, day', | |||
missing2 = 'Need valid birth date (second date): year, month, day', | |||
noMissing = true, | |||
partial = true, | |||
} | |||
local date1, date2 = getDates(frame, options) | |||
if type(date1) == 'string' then | |||
return date1 | |||
end | |||
local diff = date1 - date2 | |||
if diff.isnegative then | |||
return message('Death date (first date) must occur after birth date (second date)') | |||
end | |||
local years | |||
if diff.partial then | |||
years = diff.partial.years | |||
years = type(years) == 'table' and years[2] or years | |||
else | |||
years = diff.years | |||
end | |||
if years > 150 then | |||
return message('Invalid dates for calculating age') | |||
end | |||
local df = stripToNil(args.df) -- day first (dmy); default is month first (mdy) | |||
local result | |||
if date1.day then -- y, m, d known | |||
result = (df and | |||
'%-d %B %-Y' or | |||
'%B %-d, %-Y') .. | |||
'<span style="display:none">(%-Y-%m-%d)</span>' | |||
elseif date1.month then -- y, m known; d unknown | |||
result = | |||
'%B %-Y' .. | |||
'<span style="display:none">(%-Y-%m-00)</span>' | |||
else -- y known; m, d unknown | |||
result = | |||
'%-Y' .. | |||
'<span style="display:none">(%-Y-00-00)</span>' | |||
end | |||
result = date1:text(result) .. | |||
' (aged ' .. | |||
dateDifference({ | |||
diff = diff, | |||
show = 'y', | |||
abbr = 'abbr_off', | |||
disp = 'disp_raw', | |||
range = 'dash', | |||
sep = 'sep_space', | |||
}) .. | |||
')' | |||
local warnings = tonumber(frame.args.warnings) | |||
if warnings and warnings > 0 then | |||
local good = { | |||
df = true, | |||
mf = true, | |||
} | |||
local invalid | |||
local imax = options.textdates and 2 or 6 | |||
for k, _ in pairs(args) do | for k, _ in pairs(args) do | ||
if type(k) == 'number' then | if type(k) == 'number' then | ||
Line 923: | Line 1,011: | ||
age_generic = ageGeneric, -- can emulate several age templates | age_generic = ageGeneric, -- can emulate several age templates | ||
birth_date_and_age = bda, -- Template:Birth_date_and_age | birth_date_and_age = bda, -- Template:Birth_date_and_age | ||
death_date_and_age = dda, -- Template:Death_date_and_age | |||
gsd = dateToGsd, -- Template:Gregorian_serial_date | gsd = dateToGsd, -- Template:Gregorian_serial_date | ||
extract = dateExtract, -- Template:Extract | extract = dateExtract, -- Template:Extract |