Module:Age: Difference between revisions

    (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 noDefault = imax == 0 and getopt.noMissing
    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 and not noDefault then
    elseif not y and not m and not d then
    dates[i] = Date(flagCurrent())
    dates[i] = Date(flagCurrent())
    end
    end
    end
    end
    end
    end
    elseif not noDefault then
    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&nbsp;' ..
    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