Module:Dates
Documentation for this module may be created at Module:Dates/doc
--[[ В это модуле собраны функции, связанные с работой с датами.]]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+"=онсар, -- потом в скобках м.б. переопределено для старого стиля начиная с числа local nd=d:match("^[%d.-]*"); local od=d:match("^[%d.-]*%s*%(%s*([%d.-]*)%s*%)"); local tail = d:match("^[%d.-]+%s*%(%s*[%d.-]+%s*%)%s*(%S.*)") or d:match("^[%d.-]+%s*([^%s%d].*)"); if nd:match('^%-?%d+$' ) then return nil, nil, tonumber(nd), nil, nil, od and tonumber(od:match("%-?%d+$")),tail else local j,m,y=nd:match("^(%d+)%.(%d+)%.?(%-?%d*)"); if j then if od then local oj, om, oy = od:match("^(%d+)%.?(%d*)%.?(%-?%d*)"); return j and tonumber(j), m and tonumber(m), y>'' and tonumber(y) or nil, oj and tonumber(oj), om>'' and tonumber(om) or nil, oy>'' and tonumber(oy) or nil, tail end return j and tonumber(j), m and tonumber(m), y>'' and tonumber(y) or nil, nil, nil, nil, tail else return nil end endendlocal 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 )endlocal function Year0(y,t)-- аналог Год0 if y>0 then return table.concat{ '[[', tostring(y), ' он|', t and tostring(y)..' '..t or tostring(y), ']]' } else return table.concat{ '[[', tostring(-y), ' год до н. э.|', t and tostring(-y)..' '..t or tostring(-y), ' до н. э.]]' } endendlocal function FormDate(j,m,y,oj,om,oy,mo)-- ~ Хувь хүн/Огноо/Logic 4 if j then if not m then return "''формат неверен''" end if y then return string.format( '<span style="white-space:nowrap;">%s<span style="display:none">(<span class="%s">%04i-%02i-%02i</span>)</span></span>', table.concat( oj and ( om and ( oy and {-- ОООО СССС ӨӨ ([[ОООО]] [[СССС ӨӨ]]) oj,' ',monthg[om],' ',oy, '</span> <span style="white-space:nowrap;">([[', j, ' ', monthg[m],']] ',Year0(y),')' } or {-- ОООО СССС ӨӨ ([[ОООО]] [[СССС ӨӨ]] oj,' ',monthg[om],' ([[',j,' ',monthg[m],']]) ',Year0(y) } ) or {-- [[ОООО]] [[СССС ДД|СССС ӨӨ (ӨӨ)]] '[[',j,' ',monthg[m],'|',oj,' (',j,') ',monthg[m],']] ',Year0(y) } ) or {'[[',j,' ',monthg[m],']] ',Year0(y)} ),--/table.concat ({['Мэндэлсэн']='bday',['Нас нөгчсөн']='dday'})[mo] or '', y,m,j )--/string.format else return '<span style="white-space:nowrap;">' .. table.concat( oj and ( om and {-- СССС ӨӨ ([[СССС ӨӨ]]) oj,' ',monthg[om],' ([[',j,' ',monthg[m],']])</span>' } or {-- [[СССС ӨӨ|СССС ӨӨ (ӨӨ)]] '[[',j,' ',monthg[m],'|',oj,' (',j,') ',monthg[m],']]</span>' } ) or {'[[',j,' ',monthg[m],']]</span>'} ) end else return y and string.format( '<span style="white-space:nowrap;">%s<span style="display:none;">(<span class="bday">%04i</span>)</span></span>', Year0(y,'он'),y) or "''формат неверен''" endendlocal function GetDate(D)--dd.mm.-?yyyy или -?yyyy-mm-dd в три переменных d,m,y 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 return tonumber(d),tonumber(m),tonumber(y)endlocal function Cmp(a,b)--Сравнивает две даты, результат соответственно -1, 0 или 1 local d1,m1,y1 = GetDate(a) local d2,m2,y2 = GetDate(b) return d1 and d2 and (--nil, если формат не опознан y1==y2 and ( m1==m2 and ( d1==d2 and 0 or d1<d2 and -1 or 1 ) or m1<m2 and -1 or 1 ) or y1<y2 and -1 or 1 )endlocal 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 return tonumber(y),M,tonumber(d)endlocal 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;Yyymmdd=Yyymmdd;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;--realmonthpersdate=function(f)-- Для шаблона Хувь хүн/Огноо;{{#invoke:dates|persdate|nocat={{NAMESPACE}}}} local frame=f:getParent(); 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 = '' if d then j,m,y,oj,om,oy,tail=DecodeDate(d:gsub('−','-')); if not (j or y) then return (frame.args.nocat and d or d..'[[Ангилал:Википедиа:Холбоотой]]') end end; if d2 then j2,m2,y2 = DecodeDate(d2:gsub('−','-')); end; return table.concat{ 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)--возраст if not F then return '' end; local n=F(); return n and string.format(" (%i %s)%s", n, mw.getLanguage('ru'):plural(n,'он','оны','нас'), n>150 and '[[Ангилал:Википедиа:Холбоотой]]' or '' ) or '' end)( ({ ['Мэндэлсэн']=function() local now=os.date('*t'); if (not d2 or d2=='') and j and m and y then return Diffy(now.day,now.month,now.year,j,m,y) end end, ['Нас нөгчсөн']=function() return j and m and y and j2 and m2 and y2 and Diffy(j,m,y,j2,m2,y2); end, })[mo] ),--конец вызова функции возраста tail or '', 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 return FormDate(f.args[1],f.args[2],f.args[3],f.args[4],f.args[5],f.args[6],f.args['m']) else local tf=f:getParent(); return FormDate(tf.args[1],tf.args[2],tf.args[3],tf.args[4],tf.args[5],tf.args[6],tf.args['m']) endend;cmp=function(f)--Сравнивает две даты, результат соответственно -1, 0 или 1 return Cmp(f.args[1],f.args[2])end;G2J=function(f)--перевод григорианских дат в юлианские, возврат DD.MM.YYYY--Не знает про 15 октября 1582 года, не работает до нашей эры и после ???99 года--Если есть второй аргумент, преобразует только ДО этой даты включительно--Если есть третий аргумент, результат форматирует под Персона/Дата local d,m,y=GetDate(f.args[1]) if f.args[2] and Cmp(f.args[1],f.args[2])==1 then return string.format("%i.%i.%i",y,m,d) end local shift=math.floor(y/100)-math.floor(y/400)-2 if d-shift>0 then return f.args[3] and string.format("%i.%i.%i (%i)",y,m,d,d-shift) or string.format("%i.%i.%i",y,m,d-shift) else if m==1 then return f.args[3] and string.format("%i.1.%i (%i.12.%i)",d,y,31+d-shift,y-1) or string.format("%i.12.%i",31+d-shift,y-1) elseif m==3 then return f.args[3] and string.format("%i.3.%i (%i.2)", d,y, (y%4==0 and 29 or 28)+d-shift-(y%100==0 and y%400~=0 and 1 or 0) ) or string.format("%i.2.%i", (y%4==0 and 29 or 28)+d-shift-(y%100==0 and y%400~=0 and 1 or 0) ,y) else return f.args[3] and string.format( "%i.%i.%i (%i.%i)", y,m,d, monthd[m-1]+d-shift,m-1 ) or string.format("%i.%i.%i",monthd[m-1]+d-shift,m-1,y) end endend;yyyymmdd = function(f)--Переводит русскую дату в YYYY-MM-DD local y,m,d=Yyyymmdd(f.args[1]) return string.format('%4i-%02i-%02i',y,m,d)end}function table.val_to_str ( v ) if "string" == type( v ) then v = string.gsub( v, "\n", "\\n" ) if string.match( string.gsub(v,"[^'\"]",""), '^"+$' ) then return "'" .. v .. "'" end return '"' .. string.gsub(v,'"', '\\"' ) .. '"' else return "table" == type( v ) and table.tostring( v ) or tostring( v ) endendfunction table.key_to_str ( k ) if "string" == type( k ) and string.match( k, "^[_%a][_%a%d]*$" ) then return k else return "[" .. table.val_to_str( k ) .. "]" endendfunction table.tostring( tbl ) local result, done = {}, {} for k, v in ipairs( tbl ) do table.insert( result, table.val_to_str( v ) ) done[ k ] = true end for k, v in pairs( tbl ) do if not done[ k ] then table.insert( result, table.key_to_str( k ) .. "=" .. table.val_to_str( v ) ) end end return "{" .. table.concat( result, "," ) .. "}"endfunction parseISO8601Date(str)local pattern = "(%-?%d+)%-(%d+)%-(%d+)T"local Y, M, D = mw.ustring.match( str, pattern )return tonumber(Y), tonumber(M), tonumber(D)endfunction 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)endfunction 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)endfunction p.parseISO8601(str)if 'table'==type(str) thenif str.args and str.args[1] thenstr = '' .. str.args[1]elsereturn 'unknown argument type: ' .. type( str ) .. ': ' .. table.tostring( str )endendlocal 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}))endlocal 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 )if 'table'==type( time ) thenif time.args and time.args[1] thentime = tonumber( time.args[1] )elsereturn 'unknown argument type: ' .. type( time ) .. ': ' .. table.tostring( time )endendlocal 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 thenreturn p.formatWikiImpl( {year=1700, month=2, day=29}, t, infocardClass, categoryNamePrefix)endif t.year == 1800 and t.month == 3 and t.day == 12 thenreturn p.formatWikiImpl( {year=1800, month=2, day=29}, t, infocardClass, categoryNamePrefix )endif t.year == 1900 and t.month == 3 and t.day == 13 thenreturn p.formatWikiImpl( {year=1900, month=2, day=29}, t, infocardClass, categoryNamePrefix )endif g2uBoundary1 <= time and time < g2uBoundary2 thenreturn p.formatWikiImpl( os.date("*t", time - 10 * 24 * 60 * 60), t, infocardClass, categoryNamePrefix )endif g2uBoundary2 <= time and time < g2uBoundary3 thenreturn p.formatWikiImpl( os.date("*t", time - 11 * 24 * 60 * 60), t, infocardClass, categoryNamePrefix )endif g2uBoundary3 <= time and time < g2uBoundary4 thenreturn p.formatWikiImpl( os.date("*t", time - 12 * 24 * 60 * 60), t, infocardClass, categoryNamePrefix )endif g2uBoundary4 <= time and time < g2uBoundary5 thenreturn p.formatWikiImpl( os.date("*t", time - 13 * 24 * 60 * 60), t, infocardClass, categoryNamePrefix )end--только Григорианский календарьreturn p.formatWikiImpl( t, t, infocardClass, categoryNamePrefix )endfunction ternary ( cond , T , F ) if cond then return T else return F endendlocal nominativeMonthes = {'нэгдүгээр сар', 'хоёрдугаар сар', 'гуравдугаар сар', 'дөрөвдүгээр сар', 'тавдугаар сар', 'зургаадугаар сар', 'долоодугаар сар', 'наймдугаар сар', 'есдүгээр сар', 'аравдугаар сар', 'арваннэгдүгээр сар', 'арванхоёрдугаар сар'} local genitivusMonthes = {'нэгдүгээр сар', 'хоёрдугаар сар', 'гуравдугаар сар', 'дөрөвдүгээр сар', 'тавдугаар сар', 'зургаадугаар сар', 'долоодугаар сар', 'наймдугаар сар', 'есдүгээр сар', 'аравдугаар сар', 'арваннэгдүгээр сар', 'арванхоёрдугаар сар'}function nominativeYear( year ) if ( year >= 0 ) then return '[[' .. year .. ' он|' .. year .. ']]' else return '[[' .. ( 0 - year ) .. ' он до н. э.|' .. ( 0 - year ) .. ' до н. э.]]' endendfunction inYear( year ) if ( year >= 0 ) then return '' .. year .. ' онд' else return '' .. ( 0 - year) .. ' онд до н. э.' endendfunction p.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]]", genitivusMonthes[nm], nd) elseif (template == "23") then datePart = datePart .. string.format( "[[%s]] %s", nominativeYear( ny ), nominativeMonthes[nm] ) 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 "") if infocardClass then if (infocardTemplate == "123") then datePart = datePart .. '<span style="display:none">(<span class="' .. infocardClass .. '">{{padleft:' .. ny .. '|4|0}}-{{padleft:' .. nm .. '|2|0}}-{{padleft:' .. nd .. '|2|0}}</span>)</span>' elseif (infocardTemplate == "23") then datePart = datePart .. '<span style="display:none">(<span class="' .. infocardClass .. '">{{padleft:' .. ny .. '|4|0}}-{{padleft:' .. nm .. '|2|0}}</span>)</span>' elseif (infocardTemplate == "3") then datePart = datePart .. '<span style="display:none;">(<span class="' .. infocardClass .. '">{{padleft:' .. ny .. '|4|0}}</span>)</span>' endend if categoryNamePrefix then if ( nd ~= nil and nm ~= nil) then datePart = datePart .. '[[Ангилал:' .. genitivusMonthes[nm] .. ' ' .. nd .. ' ' .. categoryNamePrefix .. ']]' end if ( ny ~= nil) then datePart = datePart .. '[[Ангилал:' .. inYear( ny ) ..'-нд' .. categoryNamePrefix .. ']]' end end return datePartendreturn p
🔥 Top keywords: Нүүр хуудасТусгай:SearchБор гөрөөсЧингис хаанМонголын хаадын төр барьсан жилийн жагсаалтМөнх хаанМонголНэгдсэн Үндэстний БайгууллагаДэлхийн хоёрдугаар дайнМонгол бичигӨгэдэй хаанМонгол дахь Их Хэлмэгдүүлэлт1990 оны Монголын ардчилсан хувьсгалАгаарын бохирдолХалхын голын дайнЦахиагийн ЭлбэгдоржИх Монгол УлсЭнзимБүгд Найрамдах Монгол Ард УлсУлаанбаатарНарны аймагЮань УлсМандуул хаанАрдчилалХүний Эрхийн Түгээмэл ТунхаглалЛигдэн хаанАрдын хувьсгалОросМонгол Улсын Үндсэн ХуульХүннү улсМазаалайНисэх онгоцФотосинтезМонголын Нууц ТовчооМонгол улсын аймаг, нийслэлДашдоржийн Нацагдорж1945 оны чөлөөлөх дайнҮр хөндөлтӨмнөд Солонгос