Module:Wikidata/Dates/Test

 Documentation[créer] [purger]
-- sert à récupérer des données usuelles sur Wikidata (les fonctions élémentaires pour l'extraction des données se fait sur Module:Wikidata
-- ce module peut-être appelé par Module:InfoboxBuilder/Helpers qui les met en infobox

local wikidata = require( 'Module:Wikidata')
local formatdate = require( 'Module:Date')

local p = {}

function p.keydate( event, formatting ) -- récupère les valeurs contenues dans des qualificatifs, logique assez différente de pour les propriété principales
    if event == 'all' then event = nil end
    local claims = wikidata.getClaims({property = 'p793', targetvalue = event})
	
	if not claims or not claims[1] then
    	return "pas de claims"
    end
    local datelist = {} -- crée une liste d'objets dateobject et daterange
   
    --[[accepte plusieurs date pour un même événement, mais doivent être dans des déclarations distinctes
 	note: les tables Wikidata on une clé 0 #table n'est donc pas fiable ]]--
    for i, j in pairs(claims) do

        if not j.qualifiers then break end
        local label = "Q" .. j.mainsnak.datavalue.value['numeric-id']

        local qualif = j.qualifiers
        if qualif['p585'] and not qualif['p585'][1] then
        	object = qualif['p585'][0].datavalue.value
        	object.label = label
        	object = p.dateobject(object)
        	table.insert(datelist, object)
        elseif qualif['p580'] and qualif['p582'] and not qualif['p580'][1] and not qualif['p582'][1] then
        	begin = p.dateobject(qualif['p580'][0].datavalue.value)
        	ending = p.dateobject(qualif['p582'][0].datavalue.value)
        	object =  p.daterange(begin, ending, label)
        	table.insert(datelist, object)
        elseif qualif['p580'] and not qualif['p580'][1] then
        	begin = p.dateobject(qualif['p580'][0].datavalue.value)
        	ending = nil
        	object = p.daterange(begin, ending, label)
        	table.insert(datelist, object )
        elseif qualif['p582'] and not qualif['p582'][1] then
        	begin = nil
        	ending = p.dateobject(qualif['p582'][0].datavalue.value)
        	object = p.daterange(begin, ending, label)
        	table.insert(datelist, object)
       	end
	end

	table.sort(datelist, function(a,b) return a.timestamp < b.timestamp end)
	for i, j in pairs(datelist) do
		datelist[i] = p.objecttotext(j, formatting)
	end
	return mw.text.listToText(datelist, formatting.separator, formatting.conjunction)
end

function p.keydatewithfallback(event, fallback)
	first = p.keydate(event)
	if first ~= '' then return first end
	if not fallback then
		return ''
	end
	eventlist = {} -- liste tous les événement pertinents (créer une option pour ne retourner que le premier dans la liste ?)
	for i, j in pairs(fallback) do
		current = p.keydate(j)
		if current ~= '' then
			table.insert(eventlist, wikidata.formatEntityId(j) .. ' : ' .. current)-- indique le nom du l'événement pour éviter les imprécisions
		end
	end
	return mw.text.listToText(eventlist)
end

function p.from(d)  -- retourne "à partir de date" en langage naturel
	if d.year then year = d.year end
	if d.month then month = d.month end
	if d.day then day = d.day end
	
	if day then 
		return 'à partir du ' .. formatdate.modeleDate({day, month, year})
	elseif tonumber(month) == 4 or tonumber(month) == 8  or tonumber(month) == 10 then -- mois commençant par une voyelle
		return 'à partir d\'' .. formatdate.modeleDate({day, month, year})
	else return 
		'à partir de ' .. formatdate.modeleDate({day, month, year})
	end
end

function p.todate(d)  -- retourne "jusqu'à date' en langage naturel
	if d.year then year = d.year end
	if d.month then month = d.month end
	if d.day then day = d.day end

	if day then 
		return 'jusqu\'au ' .. formatdate.modeleDate({day, month, year})
	else return 
		'jusqu\'à' .. formatdate.modeleDate({day, month, year})
	end
end

function p.rangetotext(begin, ending)
	if not begin or not ending then return error end
	
	if begin.day then day1 = begin.day end
	if begin.month then month1 = begin.month end
	if begin.year then year1 = begin.year end

	if ending.day then day2 = ending.day end
	if ending.month then month2 = ending.month end
	if ending.year then year2 = ending.year end
       
   	if year1 == year2 then -- évite de répéter l'année si c'est deux fois la même
   		return formatdate.modeleDate({day1, month1}) .. '-' .. formatdate.modeleDate({day2, month2, year2})
    else
    	return  formatdate.modeleDate({day1, month1, year1}) .. '-' .. formatdate.modeleDate({day2, month2, year2})
    end     
 end
 
 function p.dateobject(orig) --prend une table de date Wikibase, et la retourne sous un format plus manipulable
 	local label = orig.label
 	local timestamp = orig.time
	local precision = orig.precision
	local era = '+' -- (after Christ)
	if string.sub(timestamp,1,1) == '-' or  string.sub(timestamp,2,12) == '00000000000' then  -- Before Christ or year 0 (see datamodel)
		era = '-' 
	end 
	local year = nil
	if precision >= 9 then 
		year = string.sub(timestamp, 9, 12)
		if era == '-' then -- remove one Year for BC years because of year 0
			year = tostring(tonumber(year) + 1)
		end
	end
	local month = nil
	if precision >= 10 then
		month = string.sub(timestamp, 14, 15)
	end
	local day = nil
	if precision >= 11 then
		day = string.sub(timestamp, 17, 18)
	end
	local calendar = 'gregorian' -- calendar for display, not storage
	if orig.calendarmodel == 'http://www.wikidata.org/entity/Q1985786' then
		calendar = 'julian'
		year, month, day = formatdate.gregorianToJulian( era .. year, month, day )
	end
	return {type='dateobject', timestamp = timestamp, year=year, month=month, day=day, era= era, calendar=calendar, label=label}
end

function p.daterange(date1, date2, label)
	if date1 then
		if date1.type ~= 'dateobject' then return error end
	end
	if date2 then 
		if date2.type ~= 'dateobject' then return error end
	end
	if date1 and date2 then
		if date1.timestamp > date2.timestamp then return error end -- ne pas inverser les dates, c'est sans doute un erreur
	end
	if date1 then timestamp = date1.timestamp else timestamp = date2.timestamp end
	return {type='daterange', timestamp = timestamp, begin = date1, ending = date2, label = label}
end

function p.objecttotext(object, formatting)
	text = '' 
	if object.type == 'dateobject' then
		text = text .. formatdate.modeleDate({object.day, object.month, object.era .. object.year})
	elseif object.type == 'daterange' then
		if object.begin and object.ending then
			text = text .. p.rangetotext(object.begin, object.ending)
		elseif object.begin then
			rtext = text .. p.from(object.begin)
		elseif object.ending then
			text = text .. p.todate(object.ending)
		end
	else
		return error
	end
	if formatting and formatting.showlabel == 'true' then 
		text = text .. ' : ' .. mw.wikibase.label( object.label )
	end
	return text 
end	

function p.duration(range)
	if not range.begin and range.ending then
		return nil
	else 
		a, b = range.begin, range.ending
	end
	return formatdate.age(a.year, a.month, a.day, b.year, b.month, b.day)
end

return p