dates

Этот модуль содержит функции для работы с датами.

Тестирование конвертаций

  • {{#invoke:Dates|parseISO8601|1380-09-08T00:00:00Z}} → -18596908800
  • {{#invoke:Dates|parseISO8601|1700-03-11T00:00:00Z}} → -8514374400
  • {{#invoke:Dates|parseISO8601|1799-06-06T00:00:00Z}} → -5382720000
  • {{#invoke:Dates|parseISO8601|1800-03-12T00:00:00Z}} → -5358614400
  • {{#invoke:Dates|parseISO8601|1825-12-26T00:00:00Z}} → -4544726400
  • {{#invoke:Dates|parseISO8601|1837-02-10T00:00:00Z}} → -4193596800
  • {{#invoke:Dates|parseISO8601|1900-03-13T00:00:00Z}} → -2202854400
  • {{#invoke:Dates|parseISO8601|2900-03-13T00:00:00Z}} → 29354140800
  • {{#invoke:Dates|formatWiki|-18596908800}} → Цәыббрамза 8, 1380
  • {{#invoke:Dates|formatWiki|-8514374400}} → Жәабранмза 29 (Хәажәкырамза 11), 1700
  • {{#invoke:Dates|formatWiki|-5382720000}} → Лаҵарамза 26 (Рашәарамза 6), 1799
  • {{#invoke:Dates|formatWiki|-5358614400}} → Жәабранмза 29 (Хәажәкырамза 12), 1800
  • {{#invoke:Dates|formatWiki|-5358614400}} → Ԥхынҷкәынмза 14 (26), 1825
  • {{#invoke:Dates|formatWiki|-4193596800}} → Ажьырныҳәамза 29 (Жәабранмза 10), 1837
  • {{#invoke:Dates|formatWiki|-2202854400}} → Жәабранмза 29 (Хәажәкырамза 13), 1900

--[[  В это модуле собраны функции, связанные с работой с датами. ]] 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     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)..' '..t or tostring(y), ']]'     } else return table.concat{         '[[', tostring(-y), ' год до н. э.|',          t and tostring(-y)..' '..t or tostring(-y),         ' до н. э.]]'     }     end end  local 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(             '%s(%04i-%02i-%02i)',             table.concat(                 oj and (                     om and (                         oy and {-- ММММ ДД ГГГГ ([[ММММ ДД]] [[ГГГГ]])                             monthg[om],' ',j,' ',oy,                             ' ([[',monthg[m],' ',j,']] ',Year0(y),')'                         } or {-- ММММ ДД ([[ММММ ДД]]) [[ГГГГ]]                             monthg[om],' ',oj,' ([[',monthg[m],' ',j,']]) ',Year0(y)                         }                     ) or {-- ДД [[ММММ ДД|ММММ (ДД)]] [[ГГГГ]]                         '[[',monthg[m],' ',j,'|',monthg[m],' ',oj,' (',j,')]] ',Year0(y)                     }                 ) or {'[[',monthg[m],' ',j,']] ',Year0(y)}             ),--/table.concat             ({['ииз']='bday',['иԥсыз']='dday'})[mo] or '',             y,m,j          )--/string.format         else return             '' .. table.concat(                 oj and (                     om and {-- ММММ ДД ([[ММММ ДД]])                              monthg[om],' ',oj,' ([[',monthg[m],' ',j,']])'                     } or {-- ДД [[ММММ ДД|ММММ (ДД)]]                         '[[',monthg[m],' ',j,'|',monthg[m],' ',oj,' (',j,')]]'                     }                 ) or {'[[',monthg[m],' ',j,']]'}             )         end     else         return y and string.format(             '%s(%04i)',             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+)')     if not d then y,m,d = D:match('^%s*(%-?%d+)[-\\]0*(1?%d)[-\\]0*(%d+)') end     return tonumber(d),tonumber(m),tonumber(y) end  local 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     ) 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     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; 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;--realmonth  persdate=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..'[[Category:Википедия:Статьи с ручной викификацией дат в карточке]]')      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{          '[[Category:Персоналии по алфавиту]]',          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,'шықәса')) 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 '[[Category:Википедия:Статьи о персоналиях с большим текущим возрастом]]' 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'])     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 года --Если есть второй аргумент, преобразует только ДО этой даты включительно --Если есть третий аргумент, результат форматирует под Персона/Дата     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",d,m,y)     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)",d,m,y,d-shift)         or string.format("%i.%i.%i",d-shift,m,y)     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)", d,m,y, monthd[m-1]+d-shift,m-1             )             or string.format("%i.%i.%i",monthd[m-1]+d-shift,m-1,y)         end     end end;  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 )   end end  function 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 ) .. "]"   end end  function 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, "," ) .. "}" 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 p.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  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 ) 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 nominativeYear( year )     if ( year >= 0 ) then         return '[[' .. year .. '|' .. year .. ']]'     else         return '[[Ҳ. ҟ. ' .. ( 0 - year ) .. '|ҳ. ҟ. ' .. ( 0 - year ) .. ' ш.]]'     end end  function inYear( year )     if ( year >= 0 ) then         return ''.. year ..' шықәсазы'     else         return 'ҳ. ҟ. ' .. ( 0 - year ) .. ' шықәсазы'     end end  function 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 = ''     if (template == "12") then         datePart = datePart .. string.format( "[[%s %d]]",         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( "[[%s %d]], %s",                                        genitivusMonthes[nm], nd, nominativeYear( ny ) )     elseif (template == "124") then         datePart = datePart .. string.format( "[[%s %d|%s %d (%d)]]",                                         genitivusMonthes[nm], nd, genitivusMonthes[nm],  od, nd )     elseif (template == "1234") then         datePart = datePart .. string.format( "[[%s %d|%s %d (%d)]], %s",                                         genitivusMonthes[nm], nd, genitivusMonthes[nm], od, nd,  nominativeYear( ny ) )     elseif (template == "1245") then         datePart = datePart .. string.format( "%s %d ([[%s %d]])",                                         genitivusMonthes[om], od, genitivusMonthes[nm], nd  )     elseif (template == "12345") then         datePart = datePart .. string.format( "%s %d ([[%s %d]]), %s",                                         genitivusMonthes[om], od, genitivusMonthes[nm], nd, nominativeYear( ny ) )     elseif (template == "123456") then         datePart = datePart .. string.format( '%s %d %d ([[%s %d]] %s)',                                         genitivusMonthes[om], od, oy, genitivusMonthes[nm],   nd,  nominativeYear( ny ) )     else         datePart = datePart .. 'формат неверен'     end     datePart = datePart .. ''       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 .. string.format('(%04d-%02d-%02d)', infocardClass , ny , nm , nd )     elseif (infocardTemplate == "23") then         datePart = datePart .. string.format('(%04d-%02d)', infocardClass , ny , nm )     elseif (infocardTemplate == "3") then         datePart = datePart .. string.format('(%04d)', infocardClass , ny )     end end       if categoryNamePrefix then         if ( nd ~= nil and nm ~= nil) then             datePart = datePart .. '[[Category:' .. genitivusMonthes[nm] .. ' ' .. nd .. ' рзы ' .. categoryNamePrefix .. ']]'         end         if ( ny ~= nil) then             datePart = datePart .. '[[Category:' .. inYear( ny ) .. ' ' .. categoryNamePrefix .. ']]'         end     end       return datePart end  return p 

Tags:

🔥 Trending searches on Wiki Аԥсуа:

АвикипедиаYouTube1519ИеменХрушьчов, Никита Сергеи-иԥаВаршава2005Нанҳәамза 311 (ахыԥхьаӡара)Еинштеин, АлбертИталиаҚәҭешьИорданиаМцхеҭа-МҭианеҭиУбириа (аҵакырацәара)ЖәаҩаАахыҵ УаԥстәылаБелоруссиа ақалақьқәа рсиа1553174615321802ДаниаАботаника2020Еиду Америкатәи АштатқәаГыртәыла-Хыхьтәи Шәантәыла93Аурыс бызшәа32Аҳәынҭқаррақәа рсиаКолумбиаҚырҭтәыла1793Цәыббрамза 219021960Америкатәи адоллар691198Нанҳәамза 16Наполеон БонапартАмзаМшаԥымза 29Малиа (аҵакырацәара)1030ГәыриаАспортИнгәыштәылаКурувАшықәсДауҭиа, Валери Константин-иԥаМшаԥымза 27Ихадоу адаҟьа🡆 More