Módulo:Duração

Origem: Wikipédia, a enciclopédia livre.
local p = {}

local Outils = require 'Module:Ferramentas'

-- lista de meses
local liste_mois = {
    { "janeiro", "jan.", "jan", "january", nJour = 31 },
    { "fevereiro", "fev.", "fev", "february", nJour = 28 },
    { "março", "mar.", "mar", "march", nJour = 31 },
    { "abril", "abr.", "abr", "april", nJour = 30 },
    { "maio", "mai", "mai.", "may", nJour = 31 },
    { "junho", "jun", "jun.", "june", nJour = 30 },
    { "julho", "jul.", "jul", "july", nJour = 31 },
    { "agosto", "ago", "ago.", "august", nJour = 31 },
    { "setembro", "set.", "set", "september", nJour = 30 },
    { "outubro", "out.", "out", "october", nJour = 31 },
    { "novembro", "nov.", "nov", "november", nJour = 30 },
    { "dezembro", "dez.", "dez", "december", nJour = 31 },
}

local function joursMois( m, a )
    a = a or 1
    if m == 0 then
        return 31
    elseif m == 2 then
        local b = ( a % 4 == 0 ) and ( ( a % 100 ~= 0 ) or ( a % 400 == 0 ) )
        return 28 + ( b and 1 or 0 )
    else
        return liste_mois[m].nJour
    end
end

local function erreur( texte )
    local cat = '[[Categoria:!Parâmetros desconhecidos|Duracao]]'
    local message = '<span class="error">erro : '  .. texte .. '</span>'
    local ns = mw.title.getCurrentTitle().namespace
    if ns == 0 then
        return message .. cat
    else
        return message
    end
end

---
local function determinationMois( mois )
    if tonumber( mois ) then
        local num = math.floor( tonumber( mois ) )
        if num > 0 and num <= 12 then
            return num
        end
    elseif type( mois ) == 'string' and mw.text.trim( mois ) ~= '' then
        local nom = mw.ustring.lower( mois )
        for num = 1, 12 do
            local i = 1
            while liste_mois[num][i] do
                if liste_mois[num][i] == nom then
                    return num
                end
                i = i + 1
            end
        end
    end
end

function p._duracao( args )
    local maintenant = os.date( '!*t' )
    local fuseau = mw.getContentLanguage():formatDate("Z", nil, true)/3600
    if maintenant.hour + fuseau > 23 then
        maintenant.day = maintenant.day + 1
    end

    local enjours = args["em dias"]
    local enmois = args["em meses"]
    local enanneesetjours = args["em anos e dias"]
    local enannee = not enanneesetjours and (args["em anos"])
    local raw = (args["raw"] and args["raw"] ~= "-") or (args["bruto"] and args["bruto"] ~= "-")

    local precision = 'jour'
    local jour1 = tonumber( args[1] )
    local mois1 = determinationMois( args[2] )
    local annee1 = tonumber( args[3] )
    if jour1 and jour1 > 31 and (not annee1 or annee1 <= 31) then
        local y = jour1
        jour1 = annee1
        annee1 = y
    end
    if not jour1 then
        precision = 'mois'
        -- jour1 = maintenant.day
        jour1 = 1
    end
    if not mois1 then
        if precision == 'mois' then
            precision = 'ano'
            -- mois1 = maintenant.month
            mois1 = 1
        elseif not args.noerror then
            return erreur( 'mês inválido (' .. ( args[2] or '' ) .. ')' )
        else
            return
        end
    end
    if not annee1 then
        if precision == 'ano' then
            return
            -- return erreur( 'nenhum ano fornecido' ) -- suggestion
        else
            annee1 = maintenant.year
        end
    end

    local jour2 = tonumber( args[4] ) or maintenant.day
    local mois2 = determinationMois( args[5] ) or maintenant.month
    local annee2 = tonumber( args[6])  or maintenant.year
    if jour2 > 31 and annee2 <= 31 then
        local y = jour2
        jour2 = annee2
        annee2 = y
    end
        
    local tri = os.difftime(
        os.time{ year = annee2, month = mois2, day = jour2 },
        os.time{ year = annee1, month = mois1, day = jour1 }
        ) / 86400
    if tri < 0 then
        if not args.noerror then
            return erreur( 'duração inferior a 0' )
        else
            return
        end
    end
    local nbjours = tri
    tri = 0 .. tostring( tri )
    tri = string.rep( '&', 16 - #tri ) .. tri
    local textattrs = { class = 'datasortkey', ['data-sort-value'] = tri }
    
    if enjours then
        if raw then
            return nbjours
        else
            local moduleUnite = require 'Module:Unidades'
            local unit
            if not args['esconder texto'] or args['esconder texto'] == '' then
                if nbjours> 1 then unit = 'dias' else unit = 'dia' end
            end
            nbjours = moduleUnite._unite({nbjours, unit})
            if args.sorttype == 'raw' then return nbjours else
                return mw.text.tag{ name = 'span', attrs = textattrs, content = nbjours }
            end
        end
    end

    local njour = jour2 - jour1
    local nmois = mois2 - mois1
    local nannee = annee2 - annee1
    if njour < 0 then
        nmois = nmois - 1
        njour = njour + joursMois( mois2 - 1, annee2 )
    end
    if nmois < 0 then
        nannee = nannee - 1
        nmois = nmois + 12
    end

    if enmois then
        local nbmois = nannee * 12 + nmois
        if raw then
            return nbmois
        else
            local moduleUnite = require 'Module:Unidades'
            local unit
            if not args['esconder texto'] or args['esconder texto'] == '' then
                unit = 'mois'
            end
            nbmois = moduleUnite._unite({nbmois, unit})
            if args.sorttype == 'raw' then return nbmois else
                return mw.text.tag{ name = 'span', attrs = textattrs, content = nbmois }
            end
        end
    end
    if enannee then
        if raw then
            return nannee
        else
            local moduleUnite = require 'Module:Unidades'
            local unit
            if not args['esconder texto'] or args['esconde texto'] == '' then
                if nannee > 1 then unit = 'anos' else unit = 'ano' end
            end
            nannee = moduleUnite._unite({nannee, unit})
            if args.sorttype == 'raw' then return nannee else
                return mw.text.tag{ name = 'span', attrs = textattrs, content = nannee }
            end
        end
    end

    local result = {}
    local conjunction
    local function add( nombre, singulier, pluriel )
        if nombre > 0 then
            local texte = pluriel
            if nombre == 1 then
                texte = singulier
            end
            table.insert( result, nombre .. 'ano' .. texte )
        end
    end
    if enanneesetjours then
        if args.conjtype == 'and' then conjunction = ' e ' else conjunction = ', ' end
        if precision ~= 'ano' then
            nannee = annee2 - annee1
            njour = os.difftime(
                os.time{ year = annee2, month = mois2, day = jour2 },
                os.time{ year = annee2, month = mois1, day = jour1 }
                ) / 86400
            if njour < 0 then
                nannee = nannee - 1
                njour = os.difftime(
                    os.time{ year = annee2, month = mois2, day = jour2 },
                    os.time{ year = annee2, month = 1, day = 1}
                    ) / 86400
                    + os.difftime(
                    os.time{ year = annee1 + 1, month = 1, day = 1},
                    os.time{ year = annee1, month = mois1, day = jour1 }
                    ) / 86400
            end
            add( nannee, 'ano', 'anos' )
            add( njour, 'dia', 'dias' )
        else
            add( nannee, 'ano', 'ano' )
        end
    else
        add( nannee, 'ano', 'anos' )
        if precision ~= 'ano' then
            add( nmois, 'mês', 'meses' )
        end
        if precision == 'jour' then
            add( njour, 'dia', 'dias' )
        end
    end

    if #result == 0 then
        result[1] = 'mês de um ' .. precision
        tri = 0
    end
    
    local nanneescompl = mw.text.listToText( result, nil, conjunction )
    
    if args.sorttype == 'raw' then return nanneescompl else
        return mw.text.tag{ name = 'span', attrs = textattrs, content = nanneescompl }
    end
end


function p.duracao( frame )
    local args = Outils.extractArgs( frame )
    for i = 1, 6 do
        if tonumber( args[i] ) == 0 then
            args[i] = ''
        end
    end

    return p._duracao( args )
end

return p