Відкрити головне меню

Зміни

оновлення даних
--[[ В этом модуле собраны функции, связанные с работой с датами.]]
--[[
local monthg = {'січня', 'лютого', 'березня', 'квітня', 'травня', 'червня',
В это модуле собраны функции, связанные с работой с датами.
'липня', 'серпня', "вересня", "жовтня", "листопада", "грудня"}
]]
 
local monthg = {'січня', 'лютого', 'березня', 'квітня', 'травня', 'червня', 'липня', 'серпня', 'вересня',
'жовтня', 'листопада', 'грудня'}
local monthd = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
 
local function DecodeDate(d)-- Ч, М, Г, СЧ, СМ, СГ, хвост
--дата: "%-?%d+"=год, "%d+%.%d+"=число месяца, "%d+%.%d+%.%-?%d+"=ЧМГ,
end
end
 
local function Diffy(d1,m1,y1,d0,m0,y0)--аналог Персона/Дата/Прошло лет
return y1-y0 - ( y1*y0<=0 and 1 or 0 ) - ( (m1<m0 or m1==m0 and d1<d0) and 1 or 0 )
end
 
local function Year0(y,t)-- аналог Год0
if y>0 then return table.concat{
'[[', tostring(y), ' рік|', t and tostring(y)..'&nbsp;'..t or tostring(y), ']]'
} else return table.concat{
'[[', tostring(-y), ' рік до н. е.|',
t and tostring(-y)..'&nbsp;'..t or tostring(-y),
'&nbsp;до&nbsp;н.&nbsp;е.]]'
end
end
 
local function FormDate(j,m,y,oj,om,oy,mo)-- ~ Персона/Дата/Logic 4
if j then
if y then return
string.format(
'<span styleclass="white-space:nowrap;">%s<span style="display:none">(<span class="%s">%04i-%02i-%02i</span>)</span></span>',
table.concat(
oj and (
oy and {-- ДД ММММ ГГГГ ([[ДД ММММ]] [[ГГГГ]])
oj,'&nbsp;',monthg[om],'&nbsp;',oy,
'</span> <span styleclass="white-space:nowrap;">([[',
j, ' ', monthg[m],']] ',Year0(y),')'
} or {-- ДД ММММ ([[ДД ММММ]]) [[ГГГГ]]
oj,'&nbsp;',monthg[om],' ([[',j,'&nbsp;',monthg[m],']]) ',Year0(y)
}
) or {-- ДД [[ДД ММММ|ДД (ДД) ММММ]] [[ГГГГ]]
oj,'&nbsp;[[',j,' ',monthg[m],'|',oj,'&nbsp;(',j,')&nbsp;',monthg[m],']] ',Year0(y)
}
) or {'[[',j,'&nbsp;',monthg[m],']]&nbsp;',Year0(y)}
)--/string.format
else return
'<span styleclass="white-space:nowrap;">' .. table.concat(
oj and (
om and {-- ДД ММММ ([[ДД ММММ]])
oj,'&nbsp;',monthg[om],' ([[',j,'&nbsp;',monthg[m],']])</span>'
} or {-- ДД [[ДД ММММ|ДД (ДД) ММММ]]
oj,'&nbsp;[[',j,' ',monthg[m],'|',oj,'&nbsp;(',j,')&nbsp;',monthg[m],']]</span>'
}
) or {'[[',j,'&nbsp;',monthg[m],']]</span>'}
else
return y and string.format(
'<span styleclass="white-space:nowrap;">%s<span style="display:none;">(<span class="bday">%04i</span>)</span></span>',
Year0(y,'рік'),y) or "''хибний формат''"
end
end
 
local function GetDate(D)--dd.mm.-?yyyy или -?yyyy-mm-dd в три переменных d,m,y
local d,m,y = d:match('^%s*(%d%d?)[/.]([01]?%d)[/.](%-?%d+)')
return tonumber(d),tonumber(m),tonumber(y)
end
 
local function Cmp(a,b)--Сравнивает две даты, результат соответственно -1, 0 или 1
local d1,m1,y1 = GetDate(a)
)
end
 
local function Yyyymmdd(r)--Переводит русскую дату в YYYY,MM,DD
local d, m, y, M = mw.ustring.match(r, "^%s*(%d%d?)%s+([а-яА-Я]+)%s+(%d+)")
if not m then return nil end
m = mw.ustring.lower(m)
 
for i=1,12 do if m==monthg[i] then M=i;break end end--тупо перебор
--тупо перебор
if not M then return nil end
for i = 1, 12 do
return tonumber(y),M,tonumber(d)
if m == monthg[i] then
M = i
break
end
end
 
if not M then
return nil
end
return tonumber(y), M, tonumber(d)
end
 
local p = {}
 
p = {
 
ifdate=function(f)-- Для шаблона "Если дата", имитирует старое поведение
-- Аргументы передаются шаблону
return f:getParent().args[ mw.ustring.match(frame.args[1],"^[ %d.%-−%()]*$") and 2 or 3 ]
end;
 
DecodeDate = DecodeDate;Diffy=Diffy;Year0=Year0;GetDate=GetDate;Cmp=Cmp;
Diffy = Diffy;
Yyymmdd=Yyymmdd;
Year0 = Year0;
GetDate = GetDate;
diffy=function(f)-- принимает параметры #invoke в виде двух строк-дат
Cmp = Cmp;
Yyyymmdd = Yyyymmdd;
 
diffy = function(f)-- принимает параметры #invoke в виде двух строк-дат
local d1,m1,y1=DecodeDate(f.args[1]);
local d0,m0,y0=DecodeDate(f.args[2])
return Diffy(d1,m1,y1,d0,m0,y0)
end;
 
monthg=function(f) return monthg[ f.args[1] or f:getParent().args[1] ] end;--realmonth
 
persdate=function(f)-- Для шаблона Персона/Дата;{{#invoke:dates|persdate|nocat={{NAMESPACE}}}}
local frame=f:getParent();
FormDate(j,m,y,oj,om,oy,mo),
( (frame.args['nopersoncat'] or '')~='' or (f.args['nocat'] or '')~='' ) and '' or table.concat{
'[[ККатегорія:ПерсоналииПерсоналії поза алфавитуалфавітом]]',
j and string.format('[[Категорія:%s %i %s]]',catpref[mo],j,monthg[m]) or '',
y and string.format('[[Категорія:%s в %s]]',catpref[mo],y,Year0(y,'році')) or ''
},--/table.concat внутр.
(function(F)--возраст
}--/table.concat внеш.
end;
 
formdate=function(f) -- Формирует дату по 3--6 параметрам #invoke или шаблона
--не использовать с пустыми аргументами
end
end;
 
cmp=function(f)--Сравнивает две даты, результат соответственно -1, 0 или 1
return Cmp(f.args[1],f.args[2])
end;
 
G2J=function(f)--перевод григорианских дат в юлианские, возврат DD.MM.YYYY
--Не знает про 15 октября 1582 года, не работает до нашей эры и после ???99 года
end
end;
 
-- Переводить українську дату в YYYY-MM-DD. Повертає вихідне значення, якщо дата вже в цьому форматі
yyyymmdd = function(f)--Переводит русскую дату в YYYY-MM-DD
yyyymmdd = function(f)
local y,m,d=Yyyymmdd(f.args[1])
local date, hourmin = f.args[1]
return string.format('%4i-%02i-%02i',y,m,d)
if mw.ustring.match(date, "^%s*%d+\-%d+\-%d+") then
return date
end
hourmin = mw.ustring.match(date, "%s+%d+:%d+$")
local y, m, d = Yyyymmdd(date)
if not y then
return '<span class="error">Помилка: некоректний формат дати.</span>'
end
return string.format('%4i-%02i-%02i', y, m, d) .. (hourmin or '')
end
}
 
function table.val_to_str ( v )
if "string" == type( v ) then
end
end
 
function table.key_to_str ( k )
if "string" == type( k ) and string.match( k, "^[_%a][_%a%d]*$" ) then
end
end
 
function table.tostring( tbl )
local result, done = {}, {}
return "{" .. table.concat( result, "," ) .. "}"
end
 
function parseISO8601Date(str)
local pattern = "(%-?%d+)%-(%d+)%-(%d+)T"
return tonumber(Y), tonumber(M), tonumber(D)
end
 
function parseISO8601Time(str)
local pattern = "T(%d+):(%d+):(%d+)%Z"
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 p.parseISO8601(str)
if 'table'==type(str) then
return tonumber(os.time({year=Y, month=M, day=D, hour=(h+oh), min=(m+om), sec=s}))
end
 
local g2uBoundary1 = p.parseISO8601('1582-10-15T00:00:00Z')
local g2uBoundary2 = p.parseISO8601('1700-03-12T00:00:00Z')
local g2uBoundary3 = p.parseISO8601('1800-03-13T00:00:00Z')
local g2uBoundary4 = p.parseISO8601('1900-03-14T00:00:00Z')
local g2uBoundary5 = p.parseISO8601('1918-01-26T00:00:00Z') -- декрет ЛенинаЛеніна
 
-- Передаваемое время обязано быть по Григорианскому календарю (новому стилю)
function p.formatWiki( time, infocardClass, categoryNamePrefix )
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)
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 )
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 nominativeYear( year )
if ( year >= 0 ) then
return '[[' .. year .. ' рік|' .. year .. ']]'
else
return '[[' .. ( 0 - year ) .. ' рік до н. е.|' .. ( 0 - year ) .. ' до н. е.]]'
end
end
 
function inYear( year )
if ( year >= 0 ) then
end
end
 
-- рік для категорій народження та смерті
function catbdYear( year )
else
return '' .. ( 0 - year) .. ' до н. е.'
end
end
 
function p.formatWikiImpl( t1, t2, infocardClass, categoryNamePrefix, brts )
local nd = t2.day;
local nm = t2.month;
local om = ternary ( t1.month ~= t2.month , t1.month, nil );
local oy = ternary ( t1.year ~= t2.year , t1.year, nil );
 
local bracket1 = "(";
local bracket2 = ")";
if ( brts == 1 ) then
bracket1 = "&#91;"
bracket2 = "&#93;"
end
 
local JulianComment = function(s)
return tostring(mw.html.create("abbr")
:attr("title","за юліанським календарем")
:wikitext(s)
:done())
end
 
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 styleclass="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
nd, genitivusMonthes[nm], nominativeYear( ny ) )
elseif (template == "124") then
datePart = datePart .. JulianComment(string.format( "<span title=\"за юліанським календарем\" class=\"explain\">%d</span>", [[%dod %s|(%d) %s]]",
).. string.format( " [[%d %s|" .. bracket1 .. "%d" .. bracket2 .. " %s]]",
od, nd, genitivusMonthes[nm], nd, genitivusMonthes[nm] )
nd, genitivusMonthes[nm], nd, genitivusMonthes[nm] )
elseif (template == "1234") then
datePart = datePart .. JulianComment(string.format( "<span title=\"за юліанським календарем\" class=\"explain\">%d</span>", [[%dod %s|(%d) %s]] %s",
).. string.format( " [[%d %s|" .. bracket1 .. "%d" .. bracket2 .. " %s]] %s",
od, nd, genitivusMonthes[nm], nd, genitivusMonthes[nm], nominativeYear( ny ) )
nd, genitivusMonthes[nm], nd, genitivusMonthes[nm], nominativeYear( ny ) )
elseif (template == "1245") then
datePart = datePart .. JulianComment(string.format( "<span title=\"за юліанським календарем\" class=\"explain\">%d %s</span>", (od, genitivusMonthes[[%dom] %s]])",
).. string.format(" " .. bracket1 .. "[[%d %s]]" .. bracket2 .. od, genitivusMonthes[om]"", nd, genitivusMonthes[nm] )
elseif (template == "12345") then
datePart = datePart .. JulianComment(string.format( "<span title=\"за юліанським календарем\" class=\"explain\">%d %s</span>", (od, genitivusMonthes[[%dom] %s]]) %s",
).. string.format(" " .. bracket1 .. "[[%d %s]]" .. bracket2 .. " od, genitivusMonthes[om]%s", nd, genitivusMonthes[nm], nominativeYear( ny ) )
elseif (template == "123456") then
datePart = datePart .. JulianComment(string.format( '<span title=\"за юліанським календарем\" class=\"explain\">%d %s %d</span></span>", <spanod, style="white-space:nowrap;">(genitivusMonthes[[%d %s]om], oy %s)',)
.. '</span> <span class="nowrap">'
od, genitivusMonthes[om], oy, nd, genitivusMonthes[nm], nominativeYear( ny ) )
.. string.format(" " .. bracket1 .. "[[%d %s]] %s" .. bracket2 , nd, genitivusMonthes[nm], nominativeYear( ny ) )
else
datePart = datePart .. 'хибний формат'
(nd ~= nil and "1" or "") .. (nm ~= nil and "2" or "") .. (ny ~= nil and "3" or "")
if infocardClass then
if (infocardTemplate == "123") then
datePart = datePart .. string.format('<span style="display:none">(<span class="%s">%04d-%02d-%02d</span>)</span>', infocardClass , ny , nm , nd )
elseif (infocardTemplate == "23") then
datePart = datePart .. string.format('<span style="display:none">(<span class="%s">%04d-%02d</span>)</span>', infocardClass , ny , nm )
elseif (infocardTemplate == "3") then
datePart = datePart .. string.format('<span style="display:none;">(<span class="%s">%04d</span>)</span>', infocardClass , ny )
end
end
if categoryNamePrefix then
return datePart
end
 
return p