Модуль:Wikidata/Даты2
Для документации этого модуля может быть создана страница Модуль:Wikidata/Даты2/doc
function nominativeYear( year )
if ( year >= 0 ) then
return '[[' .. year .. ' кизонь|' .. year
else
return '[[' .. ( 0 - year ) .. ' кизонь м. п. и.|' .. ( 0 - year ) .. ' м. п. и.]]'
end
end
function formatWiki( time, infocardClass, categoryNamePrefix )
if 'table'==type( time ) then
if time.args and time.args[1] then
time = tonumber( time.args[1] )
else
return 'unknown argument type: ' .. type( time ) .. ': ' .. table.tostring( time )
end
end
local t = os.date("*t", time)
if time < g2uBoundary1 then
-- выводим просто юлианский календарь. Задавать тут григорианский некорректно
return p.formatWikiImpl( t, t, infocardClass, categoryNamePrefix )
end
-- Специальные даты
if t.year == 1700 and t.month == 3 and t.day == 11 then
return p.formatWikiImpl( {year=1700, month=2, day=29}, t, infocardClass, categoryNamePrefix)
end
if t.year == 1800 and t.month == 3 and t.day == 12 then
return p.formatWikiImpl( {year=1800, month=2, day=29}, t, infocardClass, categoryNamePrefix )
end
if t.year == 1900 and t.month == 3 and t.day == 13 then
return p.formatWikiImpl( {year=1900, month=2, day=29}, t, infocardClass, categoryNamePrefix )
end
if g2uBoundary1 <= time and time < g2uBoundary2 then
return p.formatWikiImpl( os.date("*t", time - 10 * 24 * 60 * 60), t, infocardClass, categoryNamePrefix )
end
if g2uBoundary2 <= time and time < g2uBoundary3 then
return p.formatWikiImpl( os.date("*t", time - 11 * 24 * 60 * 60), t, infocardClass, categoryNamePrefix )
end
if g2uBoundary3 <= time and time < g2uBoundary4 then
return p.formatWikiImpl( os.date("*t", time - 12 * 24 * 60 * 60), t, infocardClass, categoryNamePrefix )
end
if g2uBoundary4 <= time and time < g2uBoundary5 then
return p.formatWikiImpl( os.date("*t", time - 13 * 24 * 60 * 60), t, infocardClass, categoryNamePrefix )
end
--только Григорианский календарь
return p.formatWikiImpl( t, t, infocardClass, categoryNamePrefix )
end
function ternary ( cond , T , F )
if cond then return T else return F end
end
local nominativeMonthes = {'январьгов', 'февральков', 'марков', 'апрельков', 'майгов', 'июньков',
'июльков', 'августков', 'сентябрьков', 'октябрьков', 'ноябрьков', 'декабрьков'}
local genitivusMonthes = {'январьста', 'февральста', 'мартста', 'апрельста', 'майста', 'июньста',
'июльста', 'августста', 'сентябрьста', 'октябрьста', 'ноябрьста', 'декабрьста'}
function inYear( year )
if ( year >= 0 ) then
return '' .. year .. ' кизоня'
else
return '' .. ( 0 - year) .. ' кизоня м. п. и.'
end
end
function formatWikiImpl( t1, t2, infocardClass, categoryNamePrefix )
local nd = t2.day;
local nm = t2.month;
local ny = t2.year;
local od = ternary ( t1.day ~= t2.day , t1.day, nil );
local om = ternary ( t1.month ~= t2.month , t1.month, nil );
local oy = ternary ( t1.year ~= t2.year , t1.year, nil );
local template =
(nd ~= nil and "1" or "") .. (nm ~= nil and "2" or "") .. (ny ~= nil and "3" or "") ..
(od ~= nil and "4" or "") .. (om ~= nil and "5" or "") .. (oy ~= nil and "6" or "")
local datePart = '<span style="white-space:nowrap;">'
if (template == "12") then
datePart = datePart .. string.format( "[[%d %s]]",
nd, genitivusMonthes[nm] )
elseif (template == "23") then
datePart = datePart .. string.format( "[[%s]] %s",
nominativeMonthes[nm], nominativeYear( ny ) ) .. ' кизоня]]'
elseif (template == "3") then
datePart = datePart .. nominativeYear( ny ) .. ' кизонь]]'
elseif (template == "123") then
datePart = datePart .. string.format( "[[%d %s]] %s",
nd, genitivusMonthes[nm], nominativeYear( ny ) ) .. ' кизоня]]'
elseif (template == "124") then
datePart = datePart .. string.format( "[[%d %s|%d (%d) %s]]",
nd, genitivusMonthes[nm], od, nd, genitivusMonthes[nm] )
elseif (template == "1234") then
datePart = datePart .. string.format( "[[%d %s|%d (%d) %s]] %s",
nd, genitivusMonthes[nm], od, nd, genitivusMonthes[nm], nominativeYear( ny ) ) .. ' кизоня]]'
elseif (template == "1245") then
datePart = datePart .. string.format( "%d %s ([[%d %s]])",
od, genitivusMonthes[om], nd, genitivusMonthes[nm] )
elseif (template == "12345") then
datePart = datePart .. string.format( "%d %s ([[%d %s]]) %s",
od, genitivusMonthes[om], nd, genitivusMonthes[nm], nominativeYear( ny ) ) .. ' кизоня]]'
elseif (template == "123456") then
datePart = datePart .. string.format( '%d %s %d</span> <span style="white-space:nowrap;">([[%d %s]] %s)',
od, genitivusMonthes[om], oy, nd, genitivusMonthes[nm], nominativeYear( ny ) ) .. ' кизоня]]'
else
datePart = datePart .. 'формат неверен'
end
datePart = datePart .. '</span>'
local infocardTemplate =
(nd ~= nil and "1" or "") .. (nm ~= nil and "2" or "") .. (ny ~= nil and "3" or "")
return datePart
end
function deepcopy(orig)
local orig_type = type(orig)
local copy
if orig_type == 'table' then
copy = {}
for orig_key, orig_value in next, orig, nil do
copy[deepcopy(orig_key)] = deepcopy(orig_value)
end
setmetatable(copy, deepcopy(getmetatable(orig)))
else -- number, string, boolean, etc
copy = orig
end
return copy
end
function formatDate( value, infoclass, categoryPrefix, unknownCategory )
if value.unknown then
local result = "''неизвестно''"
if ( unknownCategory ) then
result = result .. "[[" .. unknownCategory.. "]]"
end
return result
end
-- year only
if value.precision == 9 then
local tCopy = deepcopy( value.structure )
tCopy.day = nil
tCopy.month = nil
return formatWikiImpl(tCopy, tCopy, infoclass, categoryPrefix)
end
-- year and month only
if value.precision == 10 then
local tCopy = deepcopy( value.structure )
tCopy.day = nil
return formatWikiImpl(tCopy, tCopy, infoclass, categoryPrefix)
end
if (value.calendarmodel == 'gregorian') then
return formatWikiImpl( value.structure, value.structure, infocardClass, categoryPrefix )
else
return moduleDates.formatWiki( value.time, infoclass, categoryPrefix )
end
end
-- returns table of time+precision values for specified property
function parseProperty ( propertyName )
local entity = mw.wikibase.getEntity()
if not entity or not entity.claims or not entity.claims[propertyName] then
return nil
end
local result = {}
for key, value in pairs( entity.claims[propertyName] ) do
if ( value.mainsnak.snaktype == "value" ) then
-- The calendar model used for saving the data is always the proleptic Gregorian calendar according to ISO 8601.
local timeISO6801 = tostring( value.mainsnak.datavalue.value.time )
local unixtime = parseISO8601( timeISO6801 )
local structure = os.date("*t", unixtime)
local precision = tonumber( value.mainsnak.datavalue.value.precision )
local calendarmodel = 'gregorian';
if (mw.ustring.find(value.mainsnak.datavalue.value.calendarmodel, 'Q1985786', 1, true)) then
calendarmodel = 'julian';
end
local item = { time=unixtime, structure=structure, precision=precision, calendarmodel=calendarmodel }
table.insert ( result, item )
end
if ( value.mainsnak.snaktype == "somevalue" ) then
--unknown
local item = { unknown="unknown" }
table.insert ( result, item )
end
end
return result
end
function parseISO8601Date(str)
local pattern = "(%-?%d+)%-(%d+)%-(%d+)T"
local Y, M, D = mw.ustring.match( str, pattern )
return tonumber(Y), tonumber(M), tonumber(D)
end
function parseISO8601Time(str)
local pattern = "T(%d+):(%d+):(%d+)%Z"
local H, M, S = mw.ustring.match( str, pattern)
return tonumber(H), tonumber(M), tonumber(S)
end
function parseISO8601Offset(str)
if str:sub(-1)=="Z" then return 0,0 end -- ends with Z, Zulu time
-- matches ±hh:mm, ±hhmm or ±hh; else returns nils
local pattern = "([-+])(%d%d):?(%d?%d?)$"
local sign, oh, om = mw.ustring.match( str, pattern)
sign, oh, om = sign or "+", oh or "00", om or "00"
return tonumber(sign .. oh), tonumber(sign .. om)
end
function parseISO8601(str)
if 'table'==type(str) then
if str.args and str.args[1] then
str = '' .. str.args[1]
else
return 'unknown argument type: ' .. type( str ) .. ': ' .. table.tostring( str )
end
end
local Y,M,D = parseISO8601Date(str)
local h,m,s = parseISO8601Time(str)
local oh,om = parseISO8601Offset(str)
return tonumber(os.time({year=Y, month=M, day=D, hour=(h+oh), min=(m+om), sec=s}))
end
-- проверка на совпадающие даты с разной моделью календаря
function checkDupDates( t )
if #t > 1 then
local removed = false;
local j = 1;
-- проверка на совпадающие даты с разной моделью календаря
while (j <= #t) do
local i = 1;
while (i <= #t) do
if i ~= j then
if (os.time(t[j].structure) == os.time(t[i].structure)) then
if ((t[j].calendarmodel == 'gregorian') and
(t[i].calendarmodel == 'julian')) then
removed = true;
break;
else
table.remove(t, i)
end
else
i = i + 1;
end
else
i = i + 1;
end
end
if removed then
removed = false;
table.remove(t, j);
else
j = j+1;
end
end
end
end
local p = {}
function p.dateOfReleased( )
local dTable = parseProperty ( "p571" )
if not dTable then
return ''
end
checkDupDates(dTable);
local result = ''
for key, value in pairs( dTable ) do
if result ~= '' then
result = result .. ' или '
end
if ( appendToCategory ) then
result = result .. formatDate(value, 'dday', 'Куласть ', 'К:Персоналии, чья дата смерти не установлена')
else
result = result .. formatDate(value, 'dday', nil, nil )
end
end
return result
end
function p.dateOfCreation( )
local dTable = parseProperty ( "p577" )
if not dTable then
return ''
end
checkDupDates(dTable);
local result = ''
for key, value in pairs( dTable ) do
if result ~= '' then
result = result .. ' или '
end
result = result .. formatDate(value, 'dday', nil, nil )
end
return result
end
return p