Модуль:TwitterSnowflake
Цей модуль позначений як К:реліз, готовий до загального вжитку (27). Він досягнув стадії готовності і вважається, що вільний від помилок і може використовуватись всюди, де знадобиться. Його можна вживати на допоміжних сторінках та інших сторінках Вікіпедії як можливість для навчання новачків. Аби зменшити навантаження на сервери та некоректний показ сторінок, його можна вдосконалювати в рамцях чернеткового тестування, а не з застосуванням спроб і помилок. |
Цей модуль залежить від наступних модулів: |
Це модуль Lua перетворює snowflakes[en] з таких платформ як Twitter та Discord в дату і час. Він може бути використаний для автоматичного генерування дат для таких шаблонів як {{cite tweet}}.
Використання
Є лише один обов'язковий параметр: |id_str=
, що має бути snowflake ID твіту. Наприклад, 1345021162959503360
.
{{#invoke:TwitterSnowflake|snowflakeToDate|id_str=1345021162959503360}}
поверне 1 січня 2021.
Щоб визначити формат дати, використайте |format=
.
{{#invoke:TwitterSnowflake|snowflakeToDate|id_str=1345021162959503360|format=%B %e, %Y}}
поверне січня 1, 2021 — рудимент, що лишився при перекладі модулю з англійської Вікіпедії (де є два формати дати 1 January 2021 та January 1, 2021 (американський формат, що є більш розповсюдженим)).
Зміна епохи
Стандартно використовується епоха Twitter. Щоб зазначити іншу епоху, наприклад Discord, використайте |epoch=
. Епоха Discord є 1420070400
{{#invoke:TwitterSnowflake|snowflakeToDate|id_str=797545051047460888|epoch=1420070400}}
поверне 9 січня 2021.
Див. також
Документація вище включена з Модуль:TwitterSnowflake/документація. (ред. | історія) Дописувачі можуть експериментувати на підсторінках пісочниці (ред. | різн.) та тести (створити) цього шаблону. Будь ласка, додавайте категорії до підсторінки /документація. Підсторінки цієї сторінки. |
local p = {}
local Date = require('Module:Date')._Date
function p.snowflakeToDate(frame)
local format = frame.args.format or "%e %B %Y"
local epoch = tonumber(frame.args.epoch) or 1288834974
local id_str = frame.args.id_str
if type(id_str) ~= "string" then error("помилка аргумента #1 (очікувався рядок, отримали " .. type(id_str) .. ")", 2) end
if type(format) ~= "string" then error("помилка аргумента #2 (очікувався рядок, отримали " .. type(format) .. ")", 2) end
if type(epoch) ~= "number" then error("помилка аргумента #3 (очікувалося число, отримали " .. type(epoch) .. ")", 2) end
local hi, lo = 0, 0
local hiexp = 1
local two32 = 2^32
for c in id_str:gmatch(".") do
lo = lo * 10 + c
if lo >= two32 then
hi, lo = hi * 10^hiexp + math.floor(lo / two32), lo % two32
hiexp = 1
else hiexp = hiexp + 1 end
end
hi = hi * 10^(hiexp-1)
local timestamp = math.floor((hi * 1024 + math.floor(lo / 4194304)) / 1000) + epoch
return Date(os.date(format, timestamp)):text(format:gsub("e", "-d"))
end
function p.getDate(frame)
-- just pass frame directly to snowflakeToDate, this wraps it but the args are the same plus
if (frame.args.id_str):match("%D") then -- not a number, so return -2
return -2
end
frame.args.format = "%e %B %Y"
if frame.args.date then
frame.args.date = mw.ustring.gsub(frame.args.date, "(%d%d%d%d)%a", "%1")
end
frame.args.epoch = tonumber(frame.args.epoch) or 1288834974
local epochdate = Date(os.date("%e %B %Y", frame.args.epoch))
local twitterdate = Date(p.snowflakeToDate(frame))
if twitterdate == epochdate then -- created before epoch, so can't determine the date
return -1
end
local date = Date(frame.args.date) or 0 -- if we error here, then an input of no date causes an error, which is contrary to the entire way {{TwitterSnowflake/datecheck}} works
return date - twitterdate
end
local function abs_datediff(x)
if type(x) == 'number' then return math.abs(x) end
return math.abs(x.age_days)
end
local function date_check(date)
local is_ymd = date:match("^%d%d%d%d%-%d%d%-%d%d$")
local is_dmy = mw.ustring.match(date, "^[1-9]%d?%s+%a+%s+%d%d%d%d$")
local is_mdy = mw.ustring.match(date, "^%a+%s+[1-9]%d?,%s+%d%d%d%d$")
if is_ymd or is_dmy or is_mdy then
return false
end
return true
end
function p.datecheck(frame)
local args = frame.args
if not (args.date and args.id_str) then
error('Потрібно зазначити дату та id_str, навіть якщо вони пусті.')
end
local errors = {
args.error1 or 'Дата не збігається на один чи більше днів',
args.error2 or 'Дата відсутня та допис опублікований до 4 листопада 2010',
args.error3 or 'Недійсний id_str',
args.error4 or 'Вказано дату не підтримуваного формату'
}
if mw.title.getCurrentTitle():inNamespace(0) and args.error_cat then
for i = 1, 3 do errors[i] = errors[i] .. '[[' .. args.error_cat .. ']]' end
end
if not args.date:match('^%s*$') then -- #if:{{{date|}}}
local testResult = p.getDate{ args = { date = args.date, id_str = args.id_str }}
if testResult == -2 then return errors[3] end
if date_check(args.date) then return errors[4] end
if abs_datediff(testResult) > 1 then return errors[1] end
elseif not args.id_str:match('^%s*$') then
local testResult = p.getDate{ args = { id_str = args.id_str }}
if testResult == -1 then return errors[2] end
if testResult == -2 then return errors[3] end
end
end
return p