Modulo:Data: differenze tra le versioni

Contenuto cancellato Contenuto aggiunto
rimosso valore di default per args.from
m modulo no globals obsoleto
 
(10 versioni intermedie di un altro utente non mostrate)
Riga 3:
* Utilizzato da template come {{Età wikipediana}} e {{Tempo trascorso}}.
]]
 
require('strict')
 
local getArgs = require('Modulo:Arguments').getArgs
local errorCategory = '[[Categoria:Voci con errori del modulo Data]]'
require('Modulo:No globals')
-- classe esportata
local Date = {}
 
-------------------------------------------------------------------------------
-- Funzioni di utilità
-------------------------------------------------------------------------------
 
-- Error handler per xpcall, formatta l'errore
local function errhandler(msg)
local cat = mw.title.getCurrentTitle().namespace == 0 and errorCategory or ''
return string.format('<span class="error">Errore: %s</span>%s', msg, cat)
end
 
local function isValidDate(date)
Line 15 ⟶ 25:
end
 
-- Controlla args.fromle edate inserite args.todall'utente e lile ritornarestituisce income Unixoggetti timeDate
local function parseArgs(args, isCompare)
local data1, data2, label1, label2
if not args.from then
 
error('la data di partenza è obbligatoria')
if isCompare then
elseif not isValidDate(args.from) then
data1, data2 = 'data1', 'data2'
error('la data di partenza non è valida')
label1, label2 = 'prima data', 'seconda data'
elseif not args.to then
else
error('la data di arrivo è obbligatoria')
data1, data2 = 'inizio', 'fine'
elseif isValidDate(args.to) then
error('lalabel1, label2 = 'data di arrivopartenza', non'data èdi validafine')
end
 
if not args[data1] then
error(string.format('la %s è obbligatoria', label1), 2)
elseif not isValidDate(args[data1]) then
error(string.format('la %s non è valida', label1), 2)
elseif not args[data2] then
error(string.format('la %s è obbligatoria', label2), 2)
elseif not isValidDate(args[data2]) then
error(string.format('la %s non è valida', label2), 2)
end
 
return {
d1 = tonumber(mw.getContentLanguage()Date:formatDatenew('U', args.to)[data1]),
d2 = tonumber(mw.getContentLanguage()Date:formatDatenew('U', args.from)[data2])
}
end
 
-- Error handler per xpcall, formatta l'errore
local function errhandler(msg)
return string.format('<span class="error">Errore: %s</span>', msg:match('.+%d:%s(.+)$'))
end
 
-------------------------------------------------------------------------------
-- dateDiffYMDclasse Date
-------------------------------------------------------------------------------
 
local function date_eq(t, t2)
-- Ritorna la differenza in anni, mesi e giorni tra le date d1 e d2 (Unix time).
return t.ut == t2.ut
-- Se rawTable è true ritorna una table con le chiavi: year, month, day, seconds e dir.
end
local function dateDiffYMD(d1, d2, rawTable)
local monthdays = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }
local ret = { dir = 1, seconds = math.abs(d1 - d2) }
 
local function date_lt(t, t2)
d1, d2 = os.date('*t', d1), os.date('*t', d2)
return t.ut < t2.ut
end
 
-- Costruisce un oggetto Date a partire da una stringa nel formato
-- se d1 >= d2 inverte
-- accettato dalla funzione parser #time.
if d1.year > d2.year or
function Date:new(str, precision)
(d1.year == d2.year and d1.month > d2.month) or
local self = {}
(d1.year == d2.year and d1.month == d2.month and d1.day >= d2.day) then
setmetatable(self, { __index = Date, __eq = date_eq, __lt = date_lt })
d1, d2 = d2, d1
self.ut = tonumber(mw.getContentLanguage():formatDate('U', str, true))
ret.dir = -1
self.precision = precision or 11
return self
end
 
-- Costruisce un oggetto Date a partire da una stringa nel formato:
-- "giorno mese_per_esteso anno" oppure "mese_per_esteso anno" oppure "anno".
function Date:newDMY(str)
local months = {
gennaio = 1, febbraio = 2, marzo = 3, aprile = 4, maggio = 5, giugno = 6,
luglio = 7, agosto = 8, settembre = 9, ottobre = 10, novembre = 11, dicembre = 12
}
local success, result = pcall(function()
local day, month, year = str:match("(%d+) (%a+) (%d+)")
if day then
return Date:new(string.format('%d-%d-%d', year, months[month], day))
else
month, year = str:match("(%a+) (%d+)")
if month then
return Date:new(string.format('%d-%d', year, months[month]), 10)
else
return Date:new(string.format('%d', str:match("(%d+)")), 9)
end
end
end )
return success and result or nil
end
 
-- Restituisce una stringa che rappresenta la data, senza l'ora.
function Date:getDateString()
local fmt = self.precision == 9 and 'Y' or
(self.precision == 10 and 'F Y' or
(self.precision == 11 and 'j F Y' or 'j F Y'))
return (mw.getContentLanguage():formatDate(fmt, '@' .. self.ut):gsub('^1%s', '1º '))
end
 
-- Restituisce un nuovo oggetto Date la cui data è avanzata del numero di giorni specificati.
function Date:addDays(days)
return Date:new('@' .. (self.ut + days * 86400))
end
 
-- Funzione di utilità per Date:diffYMD e Date:diff
-- Aggiunge un eventuale prefisso e suffisso al risultato invece del segno.
-- L'ultimo parametro diffVal è utilizzato solo da diff per evitare che
-- {{#invoke:Data|diff|inizio=2016/01/01|fine=2015/12/31|magnitudine=anni}} ritorni "-0 anni".
local function formatResult(result, date1, date2, dir, diffVal)
local ret
if dir then
-- ritorna il 'fa' anche con date1.ut == date2.ut (si potrebbe configurare con un parametro)
ret = date1.ut < date2.ut and 'tra ' .. result or result .. ' fa'
else
ret = (date1.ut <= date2.ut or diffVal == 0) and result or '-' .. result
end
return ret
end
 
-- Restituisce la differenza con la data date2 in anni, mesi e giorni.
function Date:diffYMD(date2, rawTable, dir)
local monthdays = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }
local d1, d2 = os.date('*t', self.ut), os.date('*t', date2.ut)
local ret = { seconds = math.abs(self.ut - date2.ut) }
 
if self.ut >= date2.ut then d1, d2 = d2, d1 end
 
-- anni
Line 82 ⟶ 158:
end
 
return rawTable and ret or formatResult(mw.text.listToText(ret, ',&#32;', '&#32;e&#32;'), self, date2, dir)
end
 
-- Funzione di utilità per Date:diff
-------------------------------------------------------------------------------
-- dateDiff
-------------------------------------------------------------------------------
 
-- Funzione di utilità per dateDiff
local function getMagnitudine(diff, magnitudine_min)
local units = {
Line 117 ⟶ 189:
end
 
-- Funzione di utilità per dateDiffDate:diff
local function convert(seconds, unit, text, text2)
local ret = math.floor(seconds / unit)
return ret, string.format('%s %s', ret, ret == 1 and text or text2)
end
 
-- RitornaRestituisce la differenza tracon lela date d1 edata d2 (Unix time) in solo una tra le unità:
-- anni, mesi, settimane, giorni, ore, minuti e secondi.
local function dateDiffDate:diff(d1date2, d2magnitudine, magnitudinemagnitudine_min, magnitudine_mindir)
local diff, ret, dirval, valresult
 
diff = dateDiffYMDself:diffYMD(d1, d2date2, true)
magnitudine = magnitudine or getMagnitudine(diff, magnitudine_min)
 
if magnitudine == 'secondi' then
retval, result = convert(diff.seconds, 1, 'secondo', 'secondi')
elseif magnitudine == 'minuti' then
retval, result = convert(diff.seconds, 60, 'minuto', 'minuti')
elseif magnitudine == 'ore' then
retval, result = convert(diff.seconds, 3600, 'ora', 'ore')
elseif magnitudine == 'giorni' then
retval, result = convert(diff.seconds, 86400, 'giorno', 'giorni')
elseif magnitudine == 'settimane' then
retval, result = convert(diff.seconds, 604800, 'settimana', 'settimane')
elseif magnitudine == 'mesi' then
val = diff.years * 12 + diff.months
retresult = string.format('%s %s', val, val == 1 and 'mese' or 'mesi')
else
retval = diff.years
result = string.format('%s %s', diff.years, diff.years == 1 and 'anno' or 'anni')
end
return formatResult(result, self, date2, dir, val)
return d1 > d2 and 'tra ' .. ret or ret .. ' fa'
end
 
Line 155 ⟶ 228:
-------------------------------------------------------------------------------
 
local p = { Date = Date }
 
-- Entry point per {{#invoke:Data|diff}}
-- Per utilizzare diff da un altro modulo.
function p._diffdiff(argsframe)
local args = getArgs(frame)
local success, result = xpcall(function() return parseArgs(args) end, errhandler)
return success and dateDiff(result.d1, :diff(result.d2, args.magnitudine, args['magnitudine min'], args.dir) or result
end
 
-- Entry point per {{#invoke:Data|diff_ymd}}
-- Per utilizzare diff_ymd da un altro modulo.
function p._diff_ymddiff_ymd(argsframe)
local args = getArgs(frame)
local success, result = xpcall(function() return parseArgs(args) end, errhandler)
return success and dateDiffYMD(result.d1, :diffYMD(result.d2, false, args.dir) or result
end
 
-- Entry point per {{#invoke:Data|diffcompare}}
function p.diffcompare(frame)
local success, result = xpcall(function() return p._diffparseArgs(getArgs(frame), true) end, errhandler)
return success and (result.d1 == result.d2 and 0 or ( result.d1 < result.d2 and -1 or 1 )) or result
end
 
-- Entry point per {{#invoke:Data|diff_ymd}}
function p.diff_ymd(frame)
return p._diff_ymd(getArgs(frame))
end