Заглавная
Случайная
Войти
Настройки
О MURS вики
Отказ от ответственности
Найти
Редактирование:
Модуль:Срок
Внимание:
Вы не вошли в систему. Ваш IP-адрес будет общедоступен, если вы запишете какие-либо изменения. Если вы
войдёте
или
создадите учётную запись
, её имя будет использоваться вместо IP-адреса, наряду с другими преимуществами.
Анти-спам проверка.
Не
заполняйте это!
local p = {} local months = { ['января'] = 1, ['янв'] = 1, ['февраля'] = 2, ['фев'] = 2, ['марта'] = 3, ['мар'] = 3, ['апреля'] = 4, ['апр'] = 4, ['мая'] = 5, ['июня'] = 6, ['июн'] = 6, ['июля'] = 7, ['июл'] = 7, ['августа'] = 8, ['авг'] = 8, ['сентября'] = 9, ['сен'] = 9, ['октября'] = 10, ['окт'] = 10, ['ноября'] = 11, ['ноя'] = 11, ['декабря'] = 12, ['дек'] = 12 } -- Склонение числительных local function plural(n, f1, f2, f5) n = math.abs(n) % 100 local n1 = n % 10 if n > 10 and n < 20 then return f5 end if n1 > 1 and n1 < 5 then return f2 end if n1 == 1 then return f1 end return f5 end -- Количество дней в месяце с учётом високосного года local function daysInMonth(year, month) local daysPerMonth = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31} if month == 2 and ((year % 4 == 0 and year % 100 ~= 0) or (year % 400 == 0)) then return 29 end return daysPerMonth[month] or 30 end -- Парсинг даты local function parseDate(str) if not str or str == '' then return nil end -- Нормализация пробелов и очистка неразрывных пробелов str = mw.ustring.gsub(str, ' ', ' ') str = string.gsub(str, '\194\160', ' ') -- Очистка ссылок с пайпами: [[1703 год|1703]] -> 1703 str = mw.ustring.gsub(str, '%[%[[^%]|]*|([^%]]+)%]%]', '%1') str = mw.ustring.gsub(str, '[%[%]]', '') str = mw.ustring.gsub(str, '<!%-%-.-%-%->', '') str = mw.text.trim(str) -- Удаление окончания «года / год / г. / г» строго в конце строки ($) str = mw.ustring.gsub(str, '%s*года?%.?$', '') str = mw.ustring.gsub(str, '%s*г%.?$', '') str = mw.text.trim(str) -- Формат: 22 августа 2024 local d, mName, y = mw.ustring.match(str, '^(%d%d?)%s+([а-яё]+)%s+(%d+)$') if d and mName and y and months[mw.ustring.lower(mName)] then return tonumber(y), months[mw.ustring.lower(mName)], tonumber(d), true end -- Формат: 20.05.2024 или 20/05/2024 d, mName, y = mw.ustring.match(str, '^(%d%d?)[./](%d%d?)[./](%d+)$') if d and mName and y then return tonumber(y), tonumber(mName), tonumber(d), true end -- Формат ISO: 2024-05-20 y, mName, d = mw.ustring.match(str, '^(%d+)%-(%d%d?)%-(%d%d?)$') if y and mName and d then return tonumber(y), tonumber(mName), tonumber(d), true end -- Только месяц и год: август 2024 mName, y = mw.ustring.match(str, '^([а-яё]+)%s+(%d+)$') if mName and y and months[mw.ustring.lower(mName)] then return tonumber(y), months[mw.ustring.lower(mName)], 1, false end -- Только год: 2024, 1703, 862 y = mw.ustring.match(str, '^(%d+)$') if y then return tonumber(y), 1, 1, false end return nil end function p.diff(frame) local args = frame.args[1] and frame.args or frame:getParent().args local rawStart = args[1] or args['дата'] or args['открытие'] or args['основание'] local rawEnd = args[2] or args['до'] or args['закрытие'] or args['ликвидация'] local y1, m1, d1, hasExactDay1 = parseDate(rawStart) if not y1 then return '' end local y2, m2, d2, hasExactDay2 local isClosed = false if rawEnd and mw.text.trim(rawEnd) ~= '' and mw.text.trim(rawEnd) ~= '-' then y2, m2, d2, hasExactDay2 = parseDate(rawEnd) if y2 then isClosed = true end end if not y2 then local now = os.date('*t') y2, m2, d2 = now.year, now.month, now.day hasExactDay2 = true end -- Алгоритм расчёта разницы local showDays = (args['без_дней'] ~= 'да' and hasExactDay1 and hasExactDay2) local years = y2 - y1 local monthsCount = m2 - m1 local days = d2 - d1 if days < 0 then m2 = m2 - 1 if m2 < 1 then m2 = 12 y2 = y2 - 1 end days = days + daysInMonth(y2, m2) monthsCount = m2 - m1 years = y2 - y1 end if monthsCount < 0 then years = years - 1 monthsCount = monthsCount + 12 end if years < 0 then return '' end -- Сборка строки local parts = {} if years > 0 then table.insert(parts, years .. ' ' .. plural(years, 'год', 'года', 'лет')) end if monthsCount > 0 then table.insert(parts, monthsCount .. ' ' .. plural(monthsCount, 'месяц', 'месяца', 'месяцев')) end if showDays and days > 0 then table.insert(parts, days .. ' ' .. plural(days, 'день', 'дня', 'дней')) end local result = '' if #parts == 0 then result = showDays and 'менее суток' or 'менее месяца' elseif #parts == 1 then result = parts[1] elseif #parts == 2 then result = parts[1] .. ' и ' .. parts[2] else result = parts[1] .. ', ' .. parts[2] .. ' и ' .. parts[3] end -- 1. Только числовой результат if args['только_число'] == 'да' or args['сырой'] == 'да' then return result end -- 2. Пользовательский префикс / суффикс if args['префикс'] or args['суффикс'] then return (args['префикс'] or '') .. result .. (args['суффикс'] or '') end local mode = mw.ustring.lower(args['режим'] or args['тип'] or '') -- 3. Режим для городов и населённых пунктов if mode == 'город' or mode == 'нп' or mode == 'существует' or mode == 'основан' then if isClosed then return 'просуществовал ' .. result else return 'существует ' .. result end end -- 4. Нейтральный режим для событий, дат и годовщин if args['нейтрально'] == 'да' or args['нейтральный'] == 'да' or mode == 'нейтрально' or mode == 'событие' or mode == 'прошло' then if isClosed then return 'продлилось ' .. result else return 'прошло ' .. result end end -- 5. Режим «назад» if mode == 'назад' then return result .. ' назад' end -- 6. Стандартный транспортный режим (по умолчанию) if isClosed then return 'проработал ' .. result else return 'действует ' .. result end end return p
Описание изменений:
Пожалуйста, учтите, что любой ваш вклад в проект «MURS вики» может быть отредактирован или удалён другими участниками. Если вы не хотите, чтобы кто-либо изменял ваши тексты, не помещайте их сюда.
Вы также подтверждаете, что являетесь автором вносимых дополнений, или скопировали их из источника, допускающего свободное распространение и изменение своего содержимого (см.
MURS:Авторские права
).
НЕ РАЗМЕЩАЙТЕ БЕЗ РАЗРЕШЕНИЯ ОХРАНЯЕМЫЕ АВТОРСКИМ ПРАВОМ МАТЕРИАЛЫ!
Отменить
Справка по редактированию
(в новом окне)
Страницы, используемые на этой странице:
Шаблон:Tl
(
править
)
Модуль:Arguments
(
править
)
Модуль:Template call code
(
править
)
Модуль:Срок
(
править
)
Модуль:Срок/doc
(
править
)