3664
правки
Mansur700 (обсуждение | вклад) (Керла агӀо: «--ХIокху жимакепачохь гулбина барамаш, техьашца хIотта делла ду local monthg = {'Нажи-бутт', 'Мархи...») |
Mansur700 (обсуждение | вклад) Нет описания правки |
||
Строка 1: | Строка 1: | ||
--[[ | --[[ | ||
В это модуле собраны функции, связанные с работой с датами. | |||
]] | ]] | ||
local monthg = {' | local monthg = {'января', 'февраля', 'марта', 'апреля', 'мая', 'июня', | ||
' | 'июля', 'августа', "сентября", "октября", "ноября", "декабря"} | ||
local monthd = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31} | local monthd = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31} | ||
local function DecodeDate(d)-- | local function DecodeDate(d)-- Ч, М, Г, СЧ, СМ, СГ, хвост | ||
--дата: "%-?%d+"=год, "%d+%.%d+"= | --дата: "%-?%d+"=год, "%d+%.%d+"=число месяца, "%d+%.%d+%.%-?%d+"=ЧМГ, | ||
-- потом в скобках м.б. переопределено для старого стиля начиная с числа | -- потом в скобках м.б. переопределено для старого стиля начиная с числа | ||
local nd=d:match("^[%d.-]*"); | local nd=d:match("^[%d.-]*"); | ||
Строка 34: | Строка 34: | ||
end | end | ||
local function Diffy(d1,m1,y1,d0,m0,y0)-- | 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 ) | return y1-y0 - ( y1*y0<=0 and 1 or 0 ) - ( (m1<m0 or m1==m0 and d1<d0) and 1 or 0 ) | ||
end | end | ||
local function Year0(y,t)-- | local function Year0(y,t)-- аналог Год0 | ||
if y>0 then return table.concat{ | if y>0 then return table.concat{ | ||
'[[', tostring(y), ' год|', t and tostring(y)..' '..t or tostring(y), ']]' | '[[', tostring(y), ' год|', t and tostring(y)..' '..t or tostring(y), ']]' | ||
} else return table.concat{ | } else return table.concat{ | ||
'[[', tostring(-y), ' | '[[', tostring(-y), ' год до н. э.|', | ||
t and tostring(-y)..' '..t or tostring(-y), | t and tostring(-y)..' '..t or tostring(-y), | ||
' | ' до н. э.]]' | ||
} | } | ||
end | end | ||
end | end | ||
local function FormDate(j,m,y,oj,om,oy,mo)-- ~ | local function FormDate(j,m,y,oj,om,oy,mo)-- ~ Персона/Дата/Logic 4 | ||
if j then | if j then | ||
if not m then return "'' | if not m then return "''формат неверен''" end | ||
if y then return | if y then return | ||
string.format( | string.format( | ||
Строка 58: | Строка 58: | ||
oj and ( | oj and ( | ||
om and ( | om and ( | ||
oy and {-- ДД | oy and {-- ДД ММММ ГГГГ ([[ДД ММММ]] [[ГГГГ]]) | ||
oj,' ',monthg[om],' ',oy, | oj,' ',monthg[om],' ',oy, | ||
'</span> <span class="nowrap">([[', | '</span> <span class="nowrap">([[', | ||
j, ' ', monthg[m],']] ',Year0(y),')' | j, ' ', monthg[m],']] ',Year0(y),')' | ||
} or {-- ДД | } or {-- ДД ММММ ([[ДД ММММ]]) [[ГГГГ]] | ||
oj,' ',monthg[om],' ([[',j,' ',monthg[m],']]) ',Year0(y) | oj,' ',monthg[om],' ([[',j,' ',monthg[m],']]) ',Year0(y) | ||
} | } | ||
) or {-- ДД [[ДД | ) or {-- ДД [[ДД ММММ|(ДД) ММММ]] [[ГГГГ]] | ||
oj,' [[',j,' ',monthg[m],'|','(',j,') ',monthg[m],']] ',Year0(y) | oj,' [[',j,' ',monthg[m],'|','(',j,') ',monthg[m],']] ',Year0(y) | ||
} | } | ||
) or {'[[',j,' ',monthg[m],']] ',Year0(y)} | ) or {'[[',j,' ',monthg[m],']] ',Year0(y)} | ||
),--/table.concat | ),--/table.concat | ||
({[' | ({['Рождения']='bday',['Смерти']='dday'})[mo] or '', | ||
y,m,j | y,m,j | ||
)--/string.format | )--/string.format | ||
Строка 76: | Строка 76: | ||
'<span class="nowrap">' .. table.concat( | '<span class="nowrap">' .. table.concat( | ||
oj and ( | oj and ( | ||
om and {-- ДД | om and {-- ДД ММММ ([[ДД ММММ]]) | ||
oj,' ',monthg[om],' ([[',j,' ',monthg[m],']])</span>' | oj,' ',monthg[om],' ([[',j,' ',monthg[m],']])</span>' | ||
} or {-- ДД [[ДД | } or {-- ДД [[ДД ММММ|(ДД) ММММ]] | ||
oj,' [[',j,' ',monthg[m],'|','(',j,') ',monthg[m],']]</span>' | oj,' [[',j,' ',monthg[m],'|','(',j,') ',monthg[m],']]</span>' | ||
} | } | ||
Строка 87: | Строка 87: | ||
return y and string.format( | return y and string.format( | ||
'<span class="nowrap">%s<span style="display:none;">(<span class="bday">%04i</span>)</span></span>', | '<span class="nowrap">%s<span style="display:none;">(<span class="bday">%04i</span>)</span></span>', | ||
Year0(y,' | Year0(y,'год'),y) or "''формат неверен''" | ||
end | end | ||
end | end | ||
local function GetDate(D)--dd.mm.-?yyyy | 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+)') | local d,m,y = d:match('^%s*(%d%d?)[/.]([01]?%d)[/.](%-?%d+)') | ||
if not d then y,m,d = D:match('^%s*(%-?%d+)[-\\]0*(1?%d)[-\\]0*(%d+)') end | if not d then y,m,d = D:match('^%s*(%-?%d+)[-\\]0*(1?%d)[-\\]0*(%d+)') end | ||
Строка 97: | Строка 97: | ||
end | end | ||
local function Cmp(a,b)-- | local function Cmp(a,b)--Сравнивает две даты, результат соответственно -1, 0 или 1 | ||
local d1,m1,y1 = GetDate(a) | local d1,m1,y1 = GetDate(a) | ||
local d2,m2,y2 = GetDate(b) | local d2,m2,y2 = GetDate(b) | ||
return d1 and d2 and (--nil, | return d1 and d2 and (--nil, если формат не опознан | ||
y1==y2 and ( | y1==y2 and ( | ||
m1==m2 and ( | m1==m2 and ( | ||
Строка 109: | Строка 109: | ||
end | end | ||
local function Yyyymmdd(r)-- | local function Yyyymmdd(r)--Переводит русскую дату в YYYY,MM,DD | ||
local d, m, y, M = mw.ustring.match(r, "^%s*(%d%d?)%s+([а-яА-Я]+)%s+(%d+)") | local d, m, y, M = mw.ustring.match(r, "^%s*(%d%d?)%s+([а-яА-Я]+)%s+(%d+)") | ||
if not m then return nil end | if not m then return nil end | ||
m = mw.ustring.lower(m) | m = mw.ustring.lower(m) | ||
-- | --тупо перебор | ||
for i = 1, 12 do | for i = 1, 12 do | ||
if m == monthg[i] then | if m == monthg[i] then | ||
Строка 132: | Строка 132: | ||
p = { | p = { | ||
ifdate=function(f)-- | ifdate=function(f)-- Для шаблона "Если дата", имитирует старое поведение | ||
-- | -- Аргументы передаются шаблону | ||
return f:getParent().args[ mw.ustring.match(frame.args[1],"^[ %d.%-−%()]*$") and 2 or 3 ] | return f:getParent().args[ mw.ustring.match(frame.args[1],"^[ %d.%-−%()]*$") and 2 or 3 ] | ||
end; | end; | ||
Строка 144: | Строка 144: | ||
Yyyymmdd = Yyyymmdd; | Yyyymmdd = Yyyymmdd; | ||
diffy = function(f)-- | diffy = function(f)-- принимает параметры #invoke в виде двух строк-дат | ||
local d1,m1,y1=DecodeDate(f.args[1]); | local d1,m1,y1=DecodeDate(f.args[1]); | ||
local d0,m0,y0=DecodeDate(f.args[2]) | local d0,m0,y0=DecodeDate(f.args[2]) | ||
Строка 152: | Строка 152: | ||
monthg=function(f) return monthg[ f.args[1] or f:getParent().args[1] ] end;--realmonth | monthg=function(f) return monthg[ f.args[1] or f:getParent().args[1] ] end;--realmonth | ||
persdate=function(f)-- | persdate=function(f)-- Для шаблона Персона/Дата;{{#invoke:dates|persdate|nocat={{NAMESPACE}}}} | ||
local frame=f:getParent(); | local frame=f:getParent(); | ||
local catpref,mo,d,d2={[' | local catpref,mo,d,d2={['Рождения']='Родившиеся',['Смерти']='Умершие'}, frame.args[1],frame.args[2],frame.args[3] | ||
local cat, j,m,y,oj,om,oy,tail, j2,m2,y2, age = '' | local cat, j,m,y,oj,om,oy,tail, j2,m2,y2, age = '' | ||
if d then | if d then | ||
j,m,y,oj,om,oy,tail=DecodeDate(d:gsub('−','-')); | j,m,y,oj,om,oy,tail=DecodeDate(d:gsub('−','-')); | ||
if not (j or y) then | if not (j or y) then | ||
return (frame.args.nocat and d or d..'[[Category: | return (frame.args.nocat and d or d..'[[Category:Википедия:Статьи с ручной викификацией дат в карточке]]') | ||
end | end | ||
end; | end; | ||
Строка 168: | Строка 168: | ||
FormDate(j,m,y,oj,om,oy,mo), | FormDate(j,m,y,oj,om,oy,mo), | ||
( (frame.args['nopersoncat'] or '')~='' or (f.args['nocat'] or '')~='' ) and '' or table.concat{ | ( (frame.args['nopersoncat'] or '')~='' or (f.args['nocat'] or '')~='' ) and '' or table.concat{ | ||
'[[Category: | '[[Category:Персоналии по алфавиту]]', | ||
j and string.format('[[Category:%s %i %s]]',catpref[mo],j,monthg[m]) or '', | j and string.format('[[Category:%s %i %s]]',catpref[mo],j,monthg[m]) or '', | ||
y and string.format('[[Category:%s в %s]]',catpref[mo],y,Year0(y,' | y and string.format('[[Category:%s в %s]]',catpref[mo],y,Year0(y,'году')) or '' | ||
},--/table.concat | },--/table.concat внутр. | ||
(function(F)-- | (function(F)--возраст | ||
if not F then return '' end; | if not F then return '' end; | ||
local n=F(); | local n=F(); | ||
return n and string.format(" (%i %s)%s", | return n and string.format(" (%i %s)%s", | ||
n, | n, | ||
mw.getLanguage(' | mw.getLanguage('ru'):plural(n,'год','года','лет'), | ||
n>150 and '[[Category: | n>150 and '[[Category:Википедия:Статьи о персоналиях с большим текущим возрастом]]' or '' | ||
) or '' | ) or '' | ||
end)( ({ | end)( ({ | ||
[' | ['Рождения']=function() | ||
local now=os.date('*t'); | local now=os.date('*t'); | ||
if (not d2 or d2=='') and j and m and y then | if (not d2 or d2=='') and j and m and y then | ||
Строка 190: | Строка 190: | ||
return j and m and y and j2 and m2 and y2 and Diffy(j,m,y,j2,m2,y2); | return j and m and y and j2 and m2 and y2 and Diffy(j,m,y,j2,m2,y2); | ||
end, | end, | ||
})[mo] ),-- | })[mo] ),--конец вызова функции возраста | ||
tail or '', | tail or '', | ||
cat | cat | ||
}--/table.concat | }--/table.concat внеш. | ||
end; | end; | ||
formdate=function(f) -- | formdate=function(f) -- Формирует дату по 3--6 параметрам #invoke или шаблона | ||
-- | --не использовать с пустыми аргументами | ||
if (f.args[1] or '')~='' and (f.args[2] or '')~='' or (f.args[3] or '')~='' then | if (f.args[1] or '')~='' and (f.args[2] or '')~='' or (f.args[3] or '')~='' then | ||
return FormDate(f.args[1],f.args[2],f.args[3],f.args[4],f.args[5],f.args[6],f.args['m']) | return FormDate(f.args[1],f.args[2],f.args[3],f.args[4],f.args[5],f.args[6],f.args['m']) | ||
Строка 206: | Строка 206: | ||
end; | end; | ||
cmp=function(f)-- | cmp=function(f)--Сравнивает две даты, результат соответственно -1, 0 или 1 | ||
return Cmp(f.args[1],f.args[2]) | return Cmp(f.args[1],f.args[2]) | ||
end; | end; | ||
G2J=function(f)-- | G2J=function(f)--перевод григорианских дат в юлианские, возврат DD.MM.YYYY | ||
-- | --Не знает про 15 октября 1582 года, не работает до нашей эры и после ???99 года | ||
-- | --Если есть второй аргумент, преобразует только ДО этой даты включительно | ||
-- | --Если есть третий аргумент, результат форматирует под Персона/Дата | ||
local d,m,y=GetDate(f.args[1]) | local d,m,y=GetDate(f.args[1]) | ||
if f.args[2] and Cmp(f.args[1],f.args[2])==1 then | if f.args[2] and Cmp(f.args[1],f.args[2])==1 then | ||
Строка 243: | Строка 243: | ||
end; | end; | ||
-- | -- Переводит русскую дату в YYYY-MM-DD. Возвращает входное значение, если дата уже в этом формате | ||
yyyymmdd = function(f) | yyyymmdd = function(f) | ||
local date, hourmin = f.args[1] | local date, hourmin = f.args[1] | ||
Строка 252: | Строка 252: | ||
local y, m, d = Yyyymmdd(date) | local y, m, d = Yyyymmdd(date) | ||
if not y then | if not y then | ||
return '<span class="error"> | return '<span class="error">Ошибка: некорректный формат даты.</span>' | ||
end | end | ||
return string.format('%4i-%02i-%02i', y, m, d) .. (hourmin or '') | return string.format('%4i-%02i-%02i', y, m, d) .. (hourmin or '') | ||
Строка 294: | Строка 294: | ||
end | end | ||
function parseISO8601Date(str) | local function parseISO8601Date(str) | ||
local pattern = "(%-?%d+)%-(%d+)%-(%d+)T" | local pattern = "(%-?%d+)%-(%d+)%-(%d+)T" | ||
local Y, M, D = mw.ustring.match( str, pattern ) | local Y, M, D = mw.ustring.match( str, pattern ) | ||
Строка 300: | Строка 300: | ||
end | end | ||
function parseISO8601Time(str) | local function parseISO8601Time(str) | ||
local pattern = "T(%d+):(%d+):(%d+)%Z" | local pattern = "T(%d+):(%d+):(%d+)%Z" | ||
local H, M, S = mw.ustring.match( str, pattern) | local H, M, S = mw.ustring.match( str, pattern) | ||
Строка 306: | Строка 306: | ||
end | end | ||
function parseISO8601Offset(str) | local function parseISO8601Offset(str) | ||
if str:sub(-1)=="Z" then return 0,0 end -- ends with Z, Zulu time | if str:sub(-1)=="Z" then return 0,0 end -- ends with Z, Zulu time | ||
Строка 335: | Строка 335: | ||
local g2uBoundary3 = p.parseISO8601('1800-03-13T00:00:00Z') | local g2uBoundary3 = p.parseISO8601('1800-03-13T00:00:00Z') | ||
local g2uBoundary4 = p.parseISO8601('1900-03-14T00:00:00Z') | local g2uBoundary4 = p.parseISO8601('1900-03-14T00:00:00Z') | ||
local g2uBoundary5 = p.parseISO8601('1918-01-26T00:00:00Z') -- | local g2uBoundary5 = p.parseISO8601('1918-01-26T00:00:00Z') -- декрет Ленина | ||
-- | -- Передаваемое время обязано быть по Григорианскому календарю (новому стилю) | ||
function p.formatWiki( time, infocardClass, categoryNamePrefix ) | function p.formatWiki( time, infocardClass, categoryNamePrefix ) | ||
if 'table'==type( time ) then | if 'table'==type( time ) then | ||
Строка 348: | Строка 348: | ||
local t = os.date("*t", time) | local t = os.date("*t", time) | ||
if time < g2uBoundary1 then | if time < g2uBoundary1 then | ||
-- | -- выводим просто юлианский календарь. Задавать тут григорианский некорректно | ||
return p.formatWikiImpl( t, t, infocardClass, categoryNamePrefix ) | return p.formatWikiImpl( t, t, infocardClass, categoryNamePrefix ) | ||
end | end | ||
-- | -- Специальные даты | ||
if t.year == 1700 and t.month == 3 and t.day == 11 then | 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=1700, month=2, day=29}, t, infocardClass, categoryNamePrefix) | ||
Строка 376: | Строка 376: | ||
end | end | ||
-- | --только Григорианский календарь | ||
return p.formatWikiImpl( t, t, infocardClass, categoryNamePrefix ) | return p.formatWikiImpl( t, t, infocardClass, categoryNamePrefix ) | ||
end | end | ||
function ternary ( cond , T , F ) | local function ternary ( cond , T , F ) | ||
if cond then return T else return F end | if cond then return T else return F end | ||
end | end | ||
local nominativeMonthes = {' | local nominativeMonthes = {'январь', 'февраль', 'март', 'апрель', 'май', 'июнь', | ||
'июль', 'август', 'сентябрь', 'октябрь', 'ноябрь', 'декабрь'} | 'июль', 'август', 'сентябрь', 'октябрь', 'ноябрь', 'декабрь'} | ||
local genitivusMonthes = {'января', 'февраля', 'марта', 'апреля', 'мая', 'июня', | local genitivusMonthes = {'января', 'февраля', 'марта', 'апреля', 'мая', 'июня', | ||
' | 'июля', 'августа', 'сентября', 'октября', 'ноября', 'декабря'} | ||
function nominativeYear( year ) | local function nominativeYear( year ) | ||
if ( year >= 0 ) then | if ( year >= 0 ) then | ||
return '[[' .. year .. ' | return '[[' .. year .. ' год|' .. year .. ']]' | ||
else | else | ||
return '[[' .. ( 0 - year ) .. ' | return '[[' .. ( 0 - year ) .. ' год до н. э.|' .. ( 0 - year ) .. ' до н. э.]]' | ||
end | end | ||
end | end | ||
function inYear( year ) | local function inYear( year ) | ||
if ( year >= 0 ) then | if ( year >= 0 ) then | ||
return '' .. year .. ' | return '' .. year .. ' году' | ||
else | else | ||
return '' .. ( 0 - year) .. ' | return '' .. ( 0 - year) .. ' году до н. э.' | ||
end | end | ||
end | end | ||
function p.formatWikiImpl( t1, t2, infocardClass, categoryNamePrefix ) | function p.formatWikiImpl( t1, t2, infocardClass, categoryNamePrefix, brts ) | ||
local nd = t2.day; | local nd = t2.day; | ||
local nm = t2.month; | local nm = t2.month; | ||
Строка 413: | Строка 413: | ||
local om = ternary ( t1.month ~= t2.month , t1.month, nil ); | local om = ternary ( t1.month ~= t2.month , t1.month, nil ); | ||
local oy = ternary ( t1.year ~= t2.year , t1.year, nil ); | local oy = ternary ( t1.year ~= t2.year , t1.year, nil ); | ||
local bracket1 = "("; | |||
local bracket2 = ")"; | |||
if ( brts == 1 ) then | |||
bracket1 = "[" | |||
bracket2 = "]" | |||
end | |||
local JulianComment = function(s) | local JulianComment = function(s) | ||
return tostring(mw.html.create("abbr") | return tostring(mw.html.create("abbr") | ||
:attr("title"," | :attr("title","по юлианскому календарю") | ||
:wikitext(s) | :wikitext(s) | ||
:done()) | :done()) | ||
Строка 440: | Строка 447: | ||
elseif (template == "124") then | elseif (template == "124") then | ||
datePart = datePart .. JulianComment(string.format( "%d", od ) | datePart = datePart .. JulianComment(string.format( "%d", od ) | ||
).. string.format( " [[%d %s| | ).. string.format( " [[%d %s|" .. bracket1 .. "%d" .. bracket2 .. " %s]]", | ||
nd, genitivusMonthes[nm], nd, genitivusMonthes[nm] ) | nd, genitivusMonthes[nm], nd, genitivusMonthes[nm] ) | ||
elseif (template == "1234") then | elseif (template == "1234") then | ||
datePart = datePart .. JulianComment(string.format( "%d", od ) | datePart = datePart .. JulianComment(string.format( "%d", od ) | ||
).. string.format( " [[%d %s| | ).. string.format( " [[%d %s|" .. bracket1 .. "%d" .. bracket2 .. " %s]] %s", | ||
nd, genitivusMonthes[nm], nd, genitivusMonthes[nm], nominativeYear( ny ) ) | nd, genitivusMonthes[nm], nd, genitivusMonthes[nm], nominativeYear( ny ) ) | ||
elseif (template == "1245") then | elseif (template == "1245") then | ||
datePart = datePart .. JulianComment(string.format( "%d %s", od, genitivusMonthes[om] ) | datePart = datePart .. JulianComment(string.format( "%d %s", od, genitivusMonthes[om] ) | ||
).. string.format(" | ).. string.format(" " .. bracket1 .. "[[%d %s]]" .. bracket2 .. "", nd, genitivusMonthes[nm] ) | ||
elseif (template == "12345") then | elseif (template == "12345") then | ||
datePart = datePart .. JulianComment(string.format( "%d %s", od, genitivusMonthes[om] ) | datePart = datePart .. JulianComment(string.format( "%d %s", od, genitivusMonthes[om] ) | ||
).. string.format(" | ).. string.format(" " .. bracket1 .. "[[%d %s]]" .. bracket2 .. " %s", nd, genitivusMonthes[nm], nominativeYear( ny ) ) | ||
elseif (template == "123456") then | elseif (template == "123456") then | ||
datePart = datePart .. JulianComment(string.format( "%d %s %d", od, genitivusMonthes[om], oy )) | datePart = datePart .. JulianComment(string.format( "%d %s %d", od, genitivusMonthes[om], oy )) | ||
.. '</span> <span class="nowrap">' | .. '</span> <span class="nowrap">' | ||
.. string.format( | .. string.format(" " .. bracket1 .. "[[%d %s]] %s" .. bracket2 , nd, genitivusMonthes[nm], nominativeYear( ny ) ) | ||
else | else | ||
datePart = datePart .. ' | datePart = datePart .. 'формат неверен' | ||
end | end | ||
datePart = datePart .. '</span>' | datePart = datePart .. '</span>' |