Jump to content

Module:Human readable duration

From Wikipedia, the free encyclopedia

local p = {}

-- reproduced from Module:Convert
local scale = {
    second = 1,
    seconds = 1,
    minute = 60,
    minutes = 60,
    hour = 3600,
    hours = 3600,
    day = 86400,
    days = 86400,
    month = 2629800,
    months = 2629800,
    year = 31557600,
    years = 31557600
}

function p.main(frame)
    local args = frame:getParent().args

    local time = tonumber(args[1])

    if time == nil or time < 0 then
        return
        "<strong class='error'>Human readable duration error: First argument must be a positive number ([[Template:Human readable duration|help]])</strong>"
    end


    if scale[args[2]] == nil then
        return
        "<strong class='error'>Human readable duration error: Second argument must be a valid time unit ([[Template:Human readable duration|help]])</strong>"
    end

    local timeseconds = tonumber(args[1]) * scale[args[2]]

    if timeseconds < 59.75 then -- rounds to 59.5 seconds or less
        local converted = math.floor(timeseconds * 2 + 0.5) / 2
        return converted .. " second" .. (converted ~= 1 and "s" or "")
    elseif timeseconds < 3585 then -- rounds to 59.5 minutes or less
        local converted = math.floor(timeseconds / scale.minute * 2 + 0.5) / 2
        return converted .. " minute" .. (converted ~= 1 and "s" or "")
    elseif timeseconds < 258300 and timeseconds ~= 86400 and timeseconds ~= 172800 then -- rounds to 71.5 hours or less, excluding 24 and 48 hours exactly
        local converted = math.floor(timeseconds / scale.hour * 2 + 0.5) / 2
        return converted .. " hour" .. (converted ~= 1 and "s" or "")
    elseif timeseconds < 4341600 then -- rounds to 50 days or less
        local converted = math.floor(timeseconds / scale.day * 2 + 0.5) / 2
        return converted .. " day" .. (converted ~= 1 and "s" or "")
    elseif timeseconds < 48651300 then -- rounds to 18 months or less (rounds to nearest integer instead of 0.5)
        local converted = math.floor(timeseconds / scale.month + 0.5)
        return converted .. " month" .. (converted ~= 1 and "s" or "")
    else -- anything over 18 months rounds to nearest 0.5 years
        local converted = math.floor(timeseconds / scale.year * 2 + 0.5) / 2
        return converted .. " year" .. (converted ~= 1 and "s" or "")
    end
end

return p