మాడ్యూల్:Wikidata/Dates
Jump to navigation
Jump to search
local p = {}
local formatDate = require "Module:Complex date"
local tools = require "Module:Wikidata/Tools"
local defaultlang = mw.getCurrentFrame():callParserFunction("int", "lang")
local function splitTimestamp(timestamp, calendar)
local pattern = "(%W)(%d+)%-(%d+)%-(%d+)"
local era, year, month, day = timestamp:match(pattern)
if calendar == 'julian' then
--todo year, month, day = formatDate.gregorianToJulian( era .. year, month, day )
end
return era, year, month, day
end
local function dateObject(snak, params) --[[
transforms a Wikibase snak into a simpler table readable by Module:Complex date
{
type = "dateobject"
valuetype = corresponds to the snaktype (value, somevalue or novalue)
year = number
month = number
day = number
calendar = julian or gregorian
}
]]--
if not params then
params = {}
end
local obj = {type = "dateobject", valuetype = snak.snaktype}
if snak.snaktype == "value" then
local value = tools.getValue(snak)
obj.era, obj.year, obj.month, obj.day = splitTimestamp(value.time, value.calendar)
obj.precision = params.precision or value.precision
end
return obj
end
local function rangeObject(begin, ending)
-- object containing one or two dateobject {type = "rangeobject", begin = dateobject, ending = rangeobject}
local timestamp
if begin then
timestamp = begin.timestamp
elseif ending then
timestamp = ending.timestamp
end
return {begin = begin, ending = ending, timestamp = timestamp, type = 'rangeobject'}
end
-- Functions transforming dateobjects into date strings
local function standardDisplay(obj, precision, lang) -- returns a date in a natural language string
if obj.valuetype == "somevalue" then
return formatDate._complex_date("unknown", "", "", "", "", "", "", "", "", lang)
elseif obj.valuetype == "novalue" then
return "" -- ?
end
if precision >= 11 then
return formatDate._complex_date("", "", obj.year .. '-' .. obj.month .. '-' .. obj.day, "", "", "" , "", "", "", lang)
elseif precision == 10 then
return formatDate._complex_date("", "", obj.year .. '-' .. obj.month, "", "", "" , "", "", "", lang)
elseif precision == 9 then
return formatDate._complex_date("", "", obj.year, "", "", "" , "", "", "", lang)
elseif precision == 8 then
return formatDate._complex_date("", "", string.sub(tostring(obj.year), 1, 3) .. '0', "decade", "", "" , "", "", "", lang)
elseif precision == 7 then
return formatDate._complex_date("", "", string.sub(tostring(obj.year + 100), 1, 2), "century", "", "" , "", "", "", lang)
end
end
--- ISO format
local function ISOdate(obj, precision)
local str = ""
if obj.valuetype ~= 'value' then
return nil
end
if (precision >= 9) then
str = obj.year
end
if (precision >= 10) then
str = str .. "-" .. obj.month
end
if (precision >= 11) then
str = str .. "-" .. obj.day
end
return str
end
local function formatDatepoint(obj, params) -- takes in "datobject" and transforms it into a string
if not obj then
return nil
end
if not params then
params = {}
end
local lang = params.lang or defaultlang
local precision
if obj.valuetype == "value" then
precision = math.min(obj.precision, params.precision or 15)
end
if params.displayformat == "year" then
return obj.year
elseif params.displayformat == "isodate" then
return ISOdate(obj, precision)
else
return standardDisplay(obj, precision, lang)
end
end
local function formatDaterange(obj, params) --takes "rangeobject" and transforms it into a string
local begin = formatDatepoint(obj.begin, params)
local ending = formatDatepoint(obj.ending, params)
local str = ""
if begin then
str = str .. "from " .. begin
end
if begin and ending then
str = str .. " "
end
if ending then
str = str .. "until " .. ending
end
return str
end
local function objectToText(obj, params) -- takes any date table and transforms it into a string
if obj.type == 'dateobject' then
return formatDatepoint(obj, params)
elseif obj.type == 'rangeobject' then
return formatDaterange(obj, params)
end
return nil
end
-- Functions retrieving data from Wikidata
local function getDatefromQualif(statement, qualif)
if not(tools.hasqualifier(statement, qualif) )then
return nil
end
local v = statement.qualifiers[qualif][1]
if v.snaktype ~= 'value' then
return nil -- ?
end
return dateObject(v)
end
function p.getDate(statement) -- looks for a date in a statement (either qualifiers or main value) and returns it in the form of a "dateobject" or a "rangeobject"
-- try to use qualifiers, that can have more accurate values than the main snak
local period = getDatefromQualif(statement, 'P585') -- retourne un dateobject
if period then
return period
end
local begin, ending = getDatefromQualif(statement, 'P580'), getDatefromQualif(statement, 'P582')
if begin or ending then
return rangeObject(begin, ending) -- a rangeobject contains two dates
end
local begin, ending = getDatefromQualif(statement, 'P1319'), getDatefromQualif(statement, 'P1326')
local obj
if begin or ending then
return rangeObject(begin, ending) -- should have another parameter stating that these are not the same as with usual qualifs
end
-- else, if the main value is a time value, then return it
local mainsnak = statement.mainsnak
if mainsnak.datatype ~= 'time' then
return nil -- if the property datatype is not time, then do not use it
end
local params
return dateObject(mainsnak, params)
end
function p.getFormattedDate(statement, params)
if not statement then
return nil
end
local str
local datetable = p.getDate(statement)
if datetable then
str = objectToText(datetable, params)
end
local fuzzy = tools.hasqualifier(statement, {"P1480"}, {"Q5727902"}) -- should be moved to the getDate function
if fuzzy then
fuzzy = true
end
if fuzzy then
str = formatDate._complex_date("", "circa", str)
end
return str
end
function p.formatTimeSnak(snak, params)
local displayformat = params.displayformat
if displayformat == 'raw' then
return snak.datavalue.value.time
end
local dateobj = dateObject(snak)
return objectToText(dateobj, params)
end
return p