יחידה זו נועדה לסכום פרקי זמן, ולהציג מחרוזת המייצגת את סך הזמן. פרקי הזמן יכולים להיות בצורת שניות, דקות:שניות, או שעות:דקות:שניות. בהצגת משך הזמן ניתן לקבוע את היחידות שתהיינה בשימוש, על ידי פרמטר אופציונלי "units" או "יחידות". למרבה הצער, את היחידות עצמן יש לכתוב באנגלית. ניתן לתת רשימה של היחידות בהן מותר להשתמש: לדוגמה, אפשר לבקש הצגת הזמן בדקות ושניות בלבד, כך שבמקום "שעה, 12 דקות ו-43 שניות" נקבל "72 דקות ו-43 שניות" (למשל, כך מקובל יותר להציג אורך של אלבום מוזיקלי).

היחידות הן: 'millennia', 'centuries', 'decades', 'years', 'days', 'hours', 'minutes', 'seconds' בין היחידות השונות ניתן להפריד על ידי רווחים או סימני פיסוק כלשהם.

דוגמאות

(בגלל בעיות כיווניות, נוספו לכמה מהדוגמאות תבנית {{כ}} כפרמטר סרק, כדי להקל על קריאה ועריכה. הוספת פרמטר סרק לתבנית לא משפיעה על חישוב הזמן).

  • {{#invoke:משך זמן | sumHMS | יחידות = minutes, seconds | {{כ}} | 7211 }} מייצר את המחרוזת "120 דקות וגם 11 שניות".
  • {{#invoke:משך זמן|sumHMS | יחידות = seconds | {{כ}} | 1:0:11 | 1:00:00 }} מייצר את המחרוזת " 7,211 שניות"
  • {{#invoke:משך זמן | sumHMS | {{כ}} | 10:10:10 | 20:20:20 | 12:13:14 }} מייצר את המחרוזת "יום, 18 שעות, 43 דקות וגם 44 שניות".
  • {{#invoke:משך זמן | sumHMS | | 10:10:10 | 20:20:20 | 12:13:14 }} מייצר את המחרוזת "יום, 18 שעות, 43 דקות וגם 44 שניות".
  • {{#invoke:משך זמן | sumHMS | יחידות = years | {{כ}} | 63113999 }} מייצר את המחרוזת "שנתיים".

--[[
this module is meant for language-dependant time calculations.
ATM it exports a single function: sumHMS, which accepts unnamed (aka "order based")
arguments in the form ssss (any number of digits) or "mm:ss" or "hh:mm:ss:,
converts them all to seconds, sums them up, and returns the output string 
describing the total duration, using mw.getContentLanguage():formatDuration()
an optional paramter, "units" tells the formatting function which units to use:
e.g. {{invoke:Duration | sumHMS | 7211 | units = minutes, seconds}} will return "120 minutes and 11 seconds".
{{invoke:Duration|sumHMS| 1:0:11 | 1:00:00 | units= seconds}} will return "7211 seconds"
]]


local function sumHMS( args )
    local total = 0
    local units, kunits
    
    function oneMore( st )
        if type( st ) ~= 'string' then return end
        local t, ar = 0, { st:match( "^%s*(%d*):?(%d*):?(%d*)%s*$" ) }
        for _, v in ipairs( ar ) do
            local n = tonumber( v )
            if n then t = t * 60 + n end
        end
        total = total + t
    end

    function beenthereDoneit( factor, unit, pad, first, last )
        if kunits and not kunits[unit] then return '' end
        local res = math.floor( total / factor )
        if first and res == 0 and not last then return '' end
        total = total % factor
        return string.format( '%0' .. ( first and '1' or pad ) .. 'd' .. ( not last and ':' or '' ), res )
    end

    for _, v in ipairs( args ) do oneMore( v ) end
    if args.units or args['יחידות'] then 
        units = {}; kunits = {}
        for unit in mw.ustring.gmatch( args.units or args['יחידות'] , "%w+" ) do 
            table.insert( units, unit )
            kunits[unit] = 1
        end
    end
    if args['פלט'] == 'נא' then
        local h = beenthereDoneit( 3600, 'hours', 1, true, false )
        local m = beenthereDoneit( 60, 'minutes', 2, h == '', false )
        local s = beenthereDoneit( 1, 'seconds', 2, h == '' and m == '', true )
        return h .. m .. s  
    end
    return mw.language.getContentLanguage():formatDuration( total, units )
end

return {
    sumHMS = function( frame ) return sumHMS( frame.args ) end,
}