Перайсці да зместу

Модуль:Dates

З Вікіпедыі, свабоднай энцыклапедыі

Дакументацыю да гэтага модуля можна стварыць уМодуль:Dates/Дакументацыя

--[[
У гэтым модулі сабраны функцыі, звязаныя з працай з датамі.
]]
localmonthg={'студзеня','лютага','сакавіка','красавіка','мая','чэрвеня',
'ліпеня','жніўня',"верасня","кастрычніка","лістапада","снежня"}

localmonthd={31,28,31,30,31,30,31,31,30,31,30,31}

localfunctionDecodeDate(d)-- ГД, Х, Г, СЧ, СМ, СГ, хвост
--дата: "%-?%d+" =год, "%d+%.%d+" =чысло месяца, "%d+%.%d+%.%-?%d+" =ЧМГ,
-- потым у дужках м.б. перавызначана для старога стылю пачынаючы з чысла
localnd=d:match("^[%d.-]*");
localod=d:match("^[%d.-]*%s*%(%s*([%d.-]*)%s*%)");
localtail=d:match("^[%d.-]+%s*%(%s*[%d.-]+%s*%)%s*(%S.*)")ord:match("^[%d.-]+%s*([^%s%d].*)");
ifnd:match('^%-?%d+$')then
returnnil,nil,tonumber(nd),nil,nil,odandtonumber(od:match("%-?%d+$")),tail
else
localj,m,y=nd:match("^(%d+)%.(%d+)%.?(%-?%d*)");
ifjthen
ifodthen
localoj,om,oy=od:match("^(%d+)%.?(%d*)%.?(%-?%d*)");
returnjandtonumber(j),
mandtonumber(m),
y>''andtonumber(y)ornil,
ojandtonumber(oj),
om>''andtonumber(om)ornil,
oy>''andtonumber(oy)ornil,
tail
end
returnjandtonumber(j),mandtonumber(m),y>''andtonumber(y)ornil,nil,nil,nil,tail
elsereturnnil
end
end
end

localfunctionDiffy(d1,m1,y1,d0,m0,y0)--аналаг Асоба/Дата/Прайшло гадоў
returny1-y0-(y1*y0<=0and1or0)-((m1<m0orm1==m0andd1<d0)and1or0)
end

localfunctionYear0(y,t)-- аналаг Год0
ify>0thenreturntable.concat{
'[[',tostring(y),' |',tandtostring(y)..'&nbsp;'..tortostring(y),']]'
}elsereturntable.concat{
'[[',tostring(-y),' да н.э.|',
tandtostring(-y)..'&nbsp;'..tortostring(-y),
'&nbsp;да&nbsp;н.&nbsp;э.]]'
}
end
end

localfunctionFormDate(j,m,y,oj,om,oy,mo)-- ~ Асоба/Дата/Logic 4
ifjthen
ifnotmthenreturn"''няслушны фармат''"end
ifythenreturn
string.format(
'<span style= "white-space:nowrap;" >%s<span style= "display:none" >(<span class= "%s" >%04i-%02i-%02i</span>)</span></span>',
table.concat(
ojand(
omand(
oyand{-- ДД ММММ ГГГГ ([[ДД ММММ]] [[ГГГГ]])
oj,'&nbsp;',monthg[om],'&nbsp;',oy,
'</span> <span style= "white-space:nowrap;" >([[',
j,' ',monthg[m],']] ',Year0(y),')'
}or{-- ДД ММММ ([[ДД ММММ]]) [[ГГГГ]]
oj,'&nbsp;',monthg[om],' ([[',j,'&nbsp;',monthg[m],']]) ',Year0(y)
}
)or{-- [[ДД ММММ|ДД (ДД) ММММ]] [[ГГГГ]]
'[[',j,' ',monthg[m],'|',oj,'&nbsp;(',j,')&nbsp;',monthg[m],']] ',Year0(y)
}
)or{'[[',j,'&nbsp;',monthg[m],']]&nbsp;',Year0(y)}
),--/table.concat
({['Нараджэння']='bday',['Смерці']='dday'})[mo]or'',
y,m,j
)--/string.format
elsereturn
'<span style= "white-space:nowrap;" >'..table.concat(
ojand(
omand{-- ДД ММММ ([[ДД ММММ]])
oj,'&nbsp;',monthg[om],' ([[',j,'&nbsp;',monthg[m],']])</span>'
}or{-- [[ДД ММММ|ДД (ДД) ММММ]]
'[[',j,' ',monthg[m],'|',oj,'&nbsp;(',j,')&nbsp;',monthg[m],']]</span>'
}
)or{'[[',j,'&nbsp;',monthg[m],']]</span>'}
)
end
else
returnyandstring.format(
'<span style= "white-space:nowrap;" >%s<span style= "display:none;" >(<span class= "bday" >%04i</span>)</span></span>',
Year0(y,'год'),y)or"''няслушны фармат''"
end
end

localfunctionGetDate(D)--dd.mm.-?yyyy ці -?yyyy-mm-dd у тры пераменных d,m,y
locald,m,y=d:match('^%s*(%d%d?)[/.]([01]?%d)[/.](%-?%d+)')
ifnotdtheny,m,d=D:match('^%s*(%-?%d+)[-\\]0*(1?%d)[-\\]0*(%d+)')end
returntonumber(d),tonumber(m),tonumber(y)
end

localfunctionCmp(a,b)--Параўноўвае дзве даты, вынік адпаведна -1, 0 ці 1
locald1,m1,y1=GetDate(a)
locald2,m2,y2=GetDate(b)
returnd1andd2and(--nil, калі фармат не апазнаны
y1==y2and(
m1==m2and(
d1==d2and0ord1<d2and-1or1
)orm1<m2and-1or1
)ory1<y2and-1or1
)
end

localfunctionYyyymmdd(r)--Перакладае беларускую дату ў YYYY,MM,DD
locald,m,y,M=mw.ustring.match(r,"^%s*(%d%d?)%s+([а-яА-Я]+)%s+(%d+)")
ifnotmthenreturnnilend
m=mw.ustring.lower(m)
fori=1,12doifm==monthg[i]thenM=i;breakendend--тупа перабор
ifnotMthenreturnnilend
returntonumber(y),M,tonumber(d)
end

localp={}

p={

ifdate=function(f)-- Для шаблона "Калі дата", імітуюць старыя паводзіны
-- Аргументы перадаюцца шаблону
returnf:getParent().args[mw.ustring.match(frame.args[1],"^[ %d.%-?%()]*$")and2or3]
end;

DecodeDate=DecodeDate;Diffy=Diffy;Year0=Year0;GetDate=GetDate;Cmp=Cmp;
Yyymmdd=Yyymmdd;

diffy=function(f)-- прымае параметры #invoke у выглядзе двух радкоў-дат
locald1,m1,y1=DecodeDate(f.args[1]);
locald0,m0,y0=DecodeDate(f.args[2])
returnDiffy(d1,m1,y1,d0,m0,y0)
end;

monthg=function(f)returnmonthg[f.args[1]orf:getParent().args[1]]end;--realmonth

persdate=function(f)-- Для шаблона Асоба/Дата;{{#invoke:dates|persdate|nocat={{NAMESPACE}}}}
localframe=f:getParent();
localcatpref,mo,d,d2={['Нараджэння']='Нарадзіліся',['Смерці']='Памерлі'},frame.args[1],frame.args[2],frame.args[3]
localcat,j,m,y,oj,om,oy,tail,j2,m2,y2,age=''
ifdthen
j,m,y,oj,om,oy,tail=DecodeDate(d:gsub('?','-'));
ifnot(jory)then
return(frame.args.nocatanddord..'[[Катэгорыя:Вікіпедыя:Артыкулы з ручной вікіфікацыяй дат у картцы]]')
end
end;
ifd2then
j2,m2,y2=DecodeDate(d2:gsub('?','-'));
end;
returntable.concat{
FormDate(j,m,y,oj,om,oy,mo),
((frame.args['nopersoncat']or'')~=''or(f.args['nocat']or'')~='')and''ortable.concat{
'[[Катэгорыя:Асобы]]',
jandstring.format('[[Катэгорыя:%s %i %s]]',catpref[mo],j,monthg[m])or'',
yandstring.format('[[Катэгорыя:%s ў %s]]',catpref[mo],y,Year0(y,'годзе'))or''
},--/table.concat унутр.
(function(F)--узрост
ifnotFthenreturn''end;
localn=F();
returnnandstring.format("(%i %s)%s",
n,
mw.getLanguage('be'):plural(n,'год','гады','гадоў'),
n>150and'[[Катэгорыя:Вікіпедыя:Артыкулы пра асоб з вялікім бягучым узростам]]'or''
)or''
end)(({
['Нараджэння']=function()
localnow=os.date('*t');
if(notd2ord2=='')andjandmandythen
returnDiffy(now.day,now.month,now.year,j,m,y)
end
end,
['Смерці']=function()
returnjandmandyandj2andm2andy2andDiffy(j,m,y,j2,m2,y2);
end,
})[mo]),--канец выкліку функцыі ўзросту
tailor'',
cat
}--/table.concat знеш.
end;

formdate=function(f)-- Фарміруе дату па 3--6 параметрам #invoke ці шаблону
--не выкарыстоўваць з пустымі аргументамі
if(f.args[1]or'')~=''and(f.args[2]or'')~=''or(f.args[3]or'')~=''then
returnFormDate(f.args[1],f.args[2],f.args[3],f.args[4],f.args[5],f.args[6],f.args['m'])
else
localtf=f:getParent();
returnFormDate(tf.args[1],tf.args[2],tf.args[3],tf.args[4],tf.args[5],tf.args[6],tf.args['m'])
end
end;

cmp=function(f)--Параўноўвае дзве даты, вынік адпаведна -1, 0 ці 1
returnCmp(f.args[1],f.args[2])
end;

G2J=function(f)--пераклад грыгарыянскіх дат у юліянскія, зварот DD.MM.YYYY
--Не ведае пра 15 кастрычніка 1582 года, не працуе да нашай эры і пасля???99 года
--Калі ёсць другі аргумент, пераўтворыць толькі ДА гэтай даты ўключна
--Калі ёсць трэці аргумент, вынік фарматуе пад Асоба/Дата
locald,m,y=GetDate(f.args[1])
iff.args[2]andCmp(f.args[1],f.args[2])==1then
returnstring.format("%i.%i.%i",d,m,y)
end
localshift=math.floor(y/100)-math.floor(y/400)-2
ifd-shift>0then
returnf.args[3]andstring.format("%i.%i.%i (%i)",d,m,y,d-shift)
orstring.format("%i.%i.%i",d-shift,m,y)
else
ifm==1then
returnf.args[3]
andstring.format("%i.1.%i (%i.12.%i)",d,y,31+d-shift,y-1)
orstring.format("%i.12.%i",31+d-shift,y-1)
elseifm==3then
returnf.args[3]andstring.format("%i.3.%i (%i.2)",d,y,
(y%4==0and29or28)+d-shift-(y%100==0andy%400~=0and1or0)
)
orstring.format("%i.2.%i",
(y%4==0and29or28)+d-shift-(y%100==0andy%400~=0and1or0)
,y)
else
returnf.args[3]andstring.format(
"%i.%i.%i (%i.%i)",d,m,y,monthd[m-1]+d-shift,m-1
)
orstring.format("%i.%i.%i",monthd[m-1]+d-shift,m-1,y)
end
end
end;

yyyymmdd=function(f)--Перакладае беларускую дату ў YYYY-MM-DD
localy,m,d=Yyyymmdd(f.args[1])
returnstring.format('%4i-%02i-%02i',y,m,d)
end
}

functiontable.val_to_str(v)
if"string"==type(v)then
v=string.gsub(v,"\n","\\n ")
ifstring.match(string.gsub(v,"[^'\ "] ",""),'^ "+$')then
return"'"..v.."'"
end
return' "'..string.gsub(v,' "','\\"')..' "'
else
return"table"==type(v)andtable.tostring(v)or
tostring(v)
end
end

functiontable.key_to_str(k)
if"string"==type(k)andstring.match(k,"^[_%a][_%a%d]*$")then
returnk
else
return"["..table.val_to_str(k).."]"
end
end

functiontable.tostring(tbl)
localresult,done={},{}
fork,vinipairs(tbl)do
table.insert(result,table.val_to_str(v))
done[k]=true
end
fork,vinpairs(tbl)do
ifnotdone[k]then
table.insert(result,
table.key_to_str(k).."="..table.val_to_str(v))
end
end
return"{"..table.concat(result,",").."}"
end

functionparseISO8601Date(str)
localpattern="(%-?%d+)%-(%d+)%-(%d+)T"
localY,M,D=mw.ustring.match(str,pattern)
returntonumber(Y),tonumber(M),tonumber(D)
end

functionparseISO8601Time(str)
localpattern="T(%d+):(%d+):(%d+)%Z"
localH,M,S=mw.ustring.match(str,pattern)
returntonumber(H),tonumber(M),tonumber(S)
end

functionparseISO8601Offset(str)
ifstr:sub(-1)=="Z"thenreturn0,0end-- ends with Z, Zulu time

-- matches ±hh:mm, ±hhmm or ±hh; else returns nils
localpattern="([-+])(%d%d):?(%d?%d?)$"
localsign,oh,om=mw.ustring.match(str,pattern)
sign,oh,om=signor"+",ohor"00",omor"00"

returntonumber(sign..oh),tonumber(sign..om)
end

functionp.parseISO8601(str)
if'table'==type(str)then
ifstr.argsandstr.args[1]then
str=''..str.args[1]
else
return'unknown argument type: '..type(str)..': '..table.tostring(str)
end
end
localY,M,D=parseISO8601Date(str)
localh,m,s=parseISO8601Time(str)
localoh,om=parseISO8601Offset(str)
returntonumber(os.time({year=Y,month=M,day=D,hour=(h+oh),min=(m+om),sec=s}))
end

localg2uBoundary1=p.parseISO8601('1582-10-15T00:00:00Z')
localg2uBoundary2=p.parseISO8601('1700-03-12T00:00:00Z')
localg2uBoundary3=p.parseISO8601('1800-03-13T00:00:00Z')
localg2uBoundary4=p.parseISO8601('1900-03-14T00:00:00Z')
localg2uBoundary5=p.parseISO8601('1918-01-26T00:00:00Z')-- дэкрэт Леніна

-- Перадатны час абавязана быць па Грыгарыянскім календары (новым стылі)
functionp.formatWiki(time,infocardClass,categoryNamePrefix)
if'table'==type(time)then
iftime.argsandtime.args[1]then
time=tonumber(time.args[1])
else
return'unknown argument type: '..type(time)..': '..table.tostring(time)
end
end
localt=os.date("*t",time)
iftime<g2uBoundary1then
-- выводзім проста юліянскі каляндар. Задаваць тут грыгарыянскі некарэктна
returnp.formatWikiImpl(t,t,infocardClass,categoryNamePrefix)
end

-- Спецыяльныя даты
ift.year==1700andt.month==3andt.day==11then
returnp.formatWikiImpl({year=1700,month=2,day=29},t,infocardClass,categoryNamePrefix)
end
ift.year==1800andt.month==3andt.day==12then
returnp.formatWikiImpl({year=1800,month=2,day=29},t,infocardClass,categoryNamePrefix)
end
ift.year==1900andt.month==3andt.day==13then
returnp.formatWikiImpl({year=1900,month=2,day=29},t,infocardClass,categoryNamePrefix)
end

ifg2uBoundary1<=timeandtime<g2uBoundary2then
returnp.formatWikiImpl(os.date("*t",time-10*24*60*60),t,infocardClass,categoryNamePrefix)
end
ifg2uBoundary2<=timeandtime<g2uBoundary3then
returnp.formatWikiImpl(os.date("*t",time-11*24*60*60),t,infocardClass,categoryNamePrefix)
end
ifg2uBoundary3<=timeandtime<g2uBoundary4then
returnp.formatWikiImpl(os.date("*t",time-12*24*60*60),t,infocardClass,categoryNamePrefix)
end
ifg2uBoundary4<=timeandtime<g2uBoundary5then
returnp.formatWikiImpl(os.date("*t",time-13*24*60*60),t,infocardClass,categoryNamePrefix)
end

--толькі Грыгарыянскі каляндар
returnp.formatWikiImpl(t,t,infocardClass,categoryNamePrefix)
end

functionternary(cond,T,F)
ifcondthenreturnTelsereturnFend
end

localnominativeMonthes={'студзень','люты','сакавік','красавік','май','чэрвень',
'ліпень','жнівень','верасень','кастрычнік','лістапад','снежань'}

localgenitivusMonthes={'студзеня','лютага','сакавіка','красавіка','мая','чэрвеня',
'ліпеня','жніўня','верасня','кастрычніка','лістапада','снежня'}


localfunctionnominativeYear(year,nolinks)
if(year>=0)then
returnnolinksandyearor'[['..year..']]'
else
returnnolinksand(0-year)..' да н.э.'or'[['..(0-year)..' да н.э.]]'
end
end

functioninYear(year)
if(year>=0)then
return''..year..' годзе'
else
return''..(0-year)..' годзе да н.э.'
end
end

functionp.formatWikiImpl(t1,t2,infocardClass,categoryNamePrefix,leftBracket,rightBracket,nolinks)
localnd=t2.day;
localnm=t2.month;
localny=t2.year;
localod=ternary(t1.day~=t2.day,t1.day,nil);
localom=ternary(t1.month~=t2.month,t1.month,nil);
localoy=ternary(t1.year~=t2.year,t1.year,nil);

ifleftBracket==nilthen
leftBracket='('
end
ifrightBracket==nilthen
rightBracket=')'
end

localJulianComment=function(s)
returntostring(mw.html.create("abbr")
:attr("title","па юліянскім календары")
:wikitext(s)
:done())
end


localtemplate=
(nd~=niland"1"or"")..(nm~=niland"2"or"")..(ny~=niland"3"or"")..
(od~=niland"4"or"")..(om~=niland"5"or"")..(oy~=niland"6"or"")

localdatePart='<span class= "nowrap" >'
if(template=="12")then
datePart=datePart..string.format(nolinksand"%d %s"or"[[%d %s]]",
nd,genitivusMonthes[nm])
elseif(template=="23")then
datePart=datePart..string.format("%s %s",
nominativeMonthes[nm],nominativeYear(ny,nolinks))
elseif(template=="3")then
datePart=datePart..nominativeYear(ny,nolinks)
elseif(template=="123")then
datePart=datePart..string.format(nolinksand"%d %s %s"or"[[%d %s]] %s",
nd,genitivusMonthes[nm],nominativeYear(ny,nolinks))
elseif(template=="124")then
ifnolinksthen
datePart=datePart..JulianComment(string.format("%d",od)
)..string.format(""..leftBracket.."%d"..rightBracket.."%s",
nd,genitivusMonthes[nm])
else
datePart=datePart..JulianComment(string.format("%d",od)
)..string.format("[[%d %s|"..leftBracket.."%d"..rightBracket.."%s]]",
nd,genitivusMonthes[nm],nd,genitivusMonthes[nm])
end
elseif(template=="1234")then
ifnolinksthen
datePart=datePart..JulianComment(string.format("%d",od)
)..string.format(""..leftBracket.."%d"..rightBracket.."%s %s",
nd,genitivusMonthes[nm],nominativeYear(ny,nolinks))
else
datePart=datePart..JulianComment(string.format("%d",od)
)..string.format("[[%d %s|"..leftBracket.."%d"..rightBracket.."%s]] %s",
nd,genitivusMonthes[nm],nd,genitivusMonthes[nm],nominativeYear(ny,nolinks))
end
elseif(template=="1245")then
datePart=datePart..JulianComment(string.format("%d %s",od,genitivusMonthes[om])
)..string.format(""..leftBracket..(nolinksand"%d %s"or"[[%d %s]]")..rightBracket.."",nd,genitivusMonthes[nm])
elseif(template=="12345")then
datePart=datePart..JulianComment(string.format("%d %s",od,genitivusMonthes[om])
)..string.format(""..leftBracket..(nolinksand"%d %s"or"[[%d %s]]")..rightBracket.."%s",nd,genitivusMonthes[nm],nominativeYear(ny,nolinks))
elseif(template=="123456")then
datePart=datePart..JulianComment(string.format("%d %s %d",od,genitivusMonthes[om],oy))
..'</span> <span class= "nowrap" >'
..string.format(""..leftBracket..(nolinksand"%d %s %s"or"[[%d %s]] %s")..rightBracket,nd,genitivusMonthes[nm],nominativeYear(ny,nolinks))
else
datePart=datePart..'няслушны фармат'
end
datePart=datePart..'</span>'

localinfocardTemplate=
(nd~=niland"1"or"")..(nm~=niland"2"or"")..(ny~=niland"3"or"")

ifinfocardClassthen
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

ifcategoryNamePrefixthen
if(nd~=nilandnm~=nil)then
datePart=datePart..'[[Катэгорыя:'..categoryNamePrefix..' '..nd..' '..genitivusMonthes[nm]..']]'
end
if(ny~=nil)then
datePart=datePart..'[[Катэгорыя:'..categoryNamePrefix..' ў '..inYear(ny)..']]'
end
end

returndatePart
end

returnp