Vorlagenprogrammierung | Diskussionen | Lua | Unterseiten | |
Modul | Deutsch
|
Modul: | Dokumentation |
Diese Seite enthält Code in der Programmiersprache Lua. Einbindungszahl Cirrus
--[=[ Wikidata/Time 2022-10-28
Module for processing wikidata time information
Author: Vollbracht
== for use in other modules ==
* service object representing a wikidata time property
fields: year, month, day, hour, min, sec,
precision, timezone, calendarmodel
constructor:
Time:new(value) processes snack.datavalue.value e.g.
method:
Time:format(fmtStr) string representation for time object
Time:qualified(snak) snak and qualification state
Time:isLessthan(time) comparator method
Time:equals(time) comparator method
* service.LT(a, b) comparator function for table.sort e.g.
* service.equals(a, b) comparator function
* service.timify(values) table of time objects by table of values
== for use in templates ==
{{#invoke:Wikidata/Time|now|<format string>}} current system time
(mainly for testing purposes;
format string optional: defaults to wikidata time string format)
]=]
--Module globals
local _, GeneralTime = pcall(require, "Modul:Time")
local constant = GeneralTime.constant
local pointOfTime = GeneralTime.point
local p = { service={
-- more selective variant to '(.)(%d+)%-(%d+)%-(%d+)T(%d+):(%d+):(%d+)Z':
MATCHING = '(.)(%d+)%-([0-1]%d)%-([0-3]%d)T([0-2]%d):([0-6]%d):([0-6]%d)Z',
PRECISIONLEVEL = constant.PRECISIONLEVEL,
DEFAULTFORMAT = constant.DEFAULTFORMAT,
PoT='point of time'
} }
local _, DateTime = pcall(require, "Modul:DateTime")
--------------------------- local functions -----------------------------
--------------------------- service functions -----------------------------
--[[
constructor
generates a Time object
parameters:
source: (optional) table of possible time informations as of
mw.wikibase.getBestStatements(a, b)[1].mainsnak.datavalue.value
current system time if nil
NO MANDANTORY INFOS IN TABLE! OBJECT MAY CONTAIN NO TIME DATA!
]]
function p.service:new(source)
mw.log(source)
mw.log(type(source))
-- time object is UTC system time if no source specified
if not source or source == '' then
return pointOfTime:new()
end
if type(source) == "table" then
mw.logObject(source, 'from table')
local ts = source["time"]
if not ts then return pointOfTime:new(source) end
o = {}
setmetatable(o, {__index = pointOfTime})
self.__index = self
o.era, o.year, o.month, o.day, o.hour, o.min, o.sec
= ts:match(p.service.MATCHING)
o.year = tonumber(o.year)
o.month = tonumber(o.month)
o.day = tonumber(o.day)
o.hour = tonumber(o.hour)
o.min = tonumber(o.min)
o.sec = tonumber(o.sec)
o.precision = source.precision
o.timezone = source.timezone
o.calendarmodel = source.calendarmodel
o.__tostring=function()
return o:format()
end
elseif type(source) == 'string' then return pointOfTime:new(source) end
return o
end
--[[
Time:qualified(Statement)
Statement and its qualification state
parameters:
Statement a Statement that is to be qualified
returns: Statement, true if this time qualifies the snack
Statement, false if Statement is independent from this time
nil, false if this time disqualifies the snack
nil, true if Statement is nil (Ex falso quodlibet)
]]
p.service.qualified = function(this, Statement)
if not snack then return nil, true end
if type(Statement) ~= 'table' then return Statement, false end
if not Statement.qualifiers then return Statement, false end
local hasCriteria = false
-- point of time
for _, pot in ipairs(Statement.qualifiers.P585) do
local comp = p.service:new(pot.datavalue.value)
if this ~= comp then return nil, false end
hasCriteria = true;
end
-- start time
for _, pot in ipairs(Statement.qualifiers.P580) do
local comp = p.service:new(pot.datavalue.value)
if this < comp then return nil, false end
hasCriteria = true;
end
-- end time
for _, pot in ipairs(Statement.qualifiers.P582) do
local comp = p.service:new(pot.datavalue.value)
if comp < this then return nil, false end
hasCriteria = true;
end
return Statement, hasCriteria
end
--[[
Time:getFiltered(statemens)
new claim list without time disqualified claims
parameters:
statemens data source as of mw.wikidata.getBestStatements
returns: refined claimlist
]]
p.service.getFiltered = function(this, statements)
local result = {}
for _, v in ipairs(claimlist) do
local tested, tv = this:qualified(v)
if tested then table.insert(result, tested) end
end
return result
end
--[[
Time.timify(values)
table of time objects by table of values
can process statements as of mw.wikidata.getBestStatements('Q79822', 'P569')
or qualifiers for a statement
parameters:
values: table: {<source>, <source>, ...}
<source>: (requirements as of time:new() source parameter)
returns: table: {<time object>, <time object>, ...}
Time objects of <source>-elements that could be
converted are in this result table. The others are
just ignored. Hence contains initialized time
objects only.
nil if result table empty
]]
p.service.timify = function(values)
local result = {}
for _, v in ipairs(values) do
local value = v
if value.mainsnak then value = value.mainsnak end
if value.datavalue then value = value.datavalue end
if value.value then value = value.value end
local t = service.time:new(v)
if t.year then table.insert(result, t) end
end
if #result == 0 then return nil end
return result
end
--[[
Time.filtered(claimlist, timeStr)
new claim list without time disqualified claims
parameters:
claimlist data source as of mw.wikidata.getBestStatements
timeStr time given by user
returns: refined claimlist
]]
p.service.filtered = function(statements, timeStr)
local myTime = p.service:new(timeStr)
return myTime:getFiltered(statements)
end
--------------------------- template functions -----------------------------
--[[
{{#invoke:Wikidata/Time|now|<format string>}}
current system time
]]
p.now = function(frame)
return p.service:new():format(frame.args[1])
end
local testLine = function(a, b, c)
local result = '<tr style="background-color:'
if type(b) == 'boolean' then if b then b = 'true' else b = 'false' end
elseif b == nil then b = 'nil'
elseif type(b) == 'table' then
local t = b.format
if t then b = t(b) end
end
if type(c) == 'boolean' then if c then c = 'true' else c = 'false' end
elseif c == nil then c = 'nil'
elseif type(c) == 'table' then
local t = c.format
if t then c = t(c) end
end
if b == c then result = result .. '#4f4">'
else result = result .. '#f44">' end
return result .. '<td>' .. a .. '</td><td>' .. b .. '</td><td>' .. c
.. '</td></tr>'
end
p.test = function()
local result = '<table class="wikitable">'
local a = p.service:new('1.3.2000')
mw.logObject(a)
result = result .. testLine("a:format('mm-dd')", a:format('mm-dd'), '03-01')
local b = constant.STARTOFGREGORIAN
result = result .. testLine("a, b", a, b)
result = result .. testLine("a < b", a < b, false)
result = result .. testLine("a > b", a > b, true)
result = result .. testLine("a == b", a == b, false)
result = result .. testLine("a ~= b", a ~= b, true)
a = p.service:new('1582-08-15')
result = result .. testLine("a, b", a, b)
result = result .. testLine("a < b", a < b, false)
result = result .. testLine("a == b", a == b, true)
result = result .. testLine("a ~= b", a ~= b, false)
a = p.service:new()
result = result .. testLine("today", a:format('d.m.yyyy'), '2.11.2022')
result = result .. testLine("day of the week", a:dayOfTheWeek(), 4)
result = result .. testLine("day of the week", b:dayOfTheWeek(), 2)
a = p.service:new('1582-08-04')
result = result .. testLine("day of the week", a:dayOfTheWeek(), 1)
return result .. '</table>'
end
return p