Module:Human readable duration

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

"Human readable duration error: First argument must be a positive number (help)"

end

local unit = string.lower(args[2] or "")

if scale[unit] == nil then

return

"Human readable duration error: Second argument must be a valid time unit (help)"

end

local timeseconds = time * scale[unit]

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