Module:Gratisdata/Dates

local p = {} local formatDate = require "Module:Complex date" local tools = require "Module:Gratisdata/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 Gratisdata

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, 'P80') -- retourne un dateobject if period then return period end local begin, ending = getDatefromQualif(statement, 'P174'), getDatefromQualif(statement, 'P175') if begin or ending then return rangeObject(begin, ending) -- a rangeobject contains two dates end local begin, ending = getDatefromQualif(statement, 'P173'), getDatefromQualif(statement, 'P172')

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, {"P160"}, {"Q478"}) -- 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