Diff: Module:Time ago
Comparing revision #1 (2021-02-02 18:35:13) with revision #2 (2023-02-03 04:17:51).
| Old | New |
|---|---|
-- Implement [[Template:Time ago]] |
-- Implement [[Template:Time ago]] |
local numberSpell, yesno -- lazy load |
local numberSpell, yesno -- lazy load |
function numberSpell(arg) |
function numberSpell(arg) |
numberSpell = require('Module:NumberSpell')._main |
numberSpell = require('Module:NumberSpell')._main |
return numberSpell(arg) |
return numberSpell(arg) |
end |
end |
function yesno(arg) |
function yesno(arg) |
yesno = require('Module:Yesno') |
yesno = require('Module:Yesno') |
return yesno(arg) |
return yesno(arg) |
end |
end |
local p = {} |
local p = {} |
-- Table to convert entered text values to numeric values. |
-- Table to convert entered text values to numeric values. |
local timeText = { |
local timeText = { |
['seconds'] = 1, |
['seconds'] = 1, |
['minutes'] = 60, |
['minutes'] = 60, |
['hours'] = 3600, |
['hours'] = 3600, |
['days'] = 86400, |
['days'] = 86400, |
['weeks'] = 604800, |
['weeks'] = 604800, |
['months'] = 2629800, -- 365.25 * 24 * 60 * 60 / 12 |
['months'] = 2629800, -- 365.25 * 24 * 60 * 60 / 12 |
['years'] = 31557600 |
['years'] = 31557600 |
} |
} |
-- Table containing tables of possible units to use in output. |
-- Table containing tables of possible units to use in output. |
local timeUnits = { |
local timeUnits = { |
[1] = { 'second', 'seconds', "second's", "seconds'" }, |
[1] = { 'second', 'seconds', "second's", "seconds'" }, |
[60] = { 'minute', 'minutes', "minutes'", "minutes'" }, |
[60] = { 'minute', 'minutes', "minutes'", "minutes'" }, |
[3600] = { 'hour', 'hours', "hour's", "hours'" }, |
[3600] = { 'hour', 'hours', "hour's", "hours'" }, |
[86400] = { 'day', 'days', "day's", "days'" }, |
[86400] = { 'day', 'days', "day's", "days'" }, |
[604800] = { 'week', 'weeks', "week's", "weeks'", unit = 'w' }, |
[604800] = { 'week', 'weeks', "week's", "weeks'", unit = 'w' }, |
[2629800] = { 'month', 'months', "month's", "months'", unit = 'm' }, |
[2629800] = { 'month', 'months', "month's", "months'", unit = 'm' }, |
[31557600] = { 'year', 'years', "year's", "years'", unit = 'y' } |
[31557600] = { 'year', 'years', "year's", "years'", unit = 'y' } |
} |
} |
function p._main( args ) |
function p._main( args ) |
-- Initialize variables |
-- Initialize variables |
local lang = mw.language.getContentLanguage() |
local lang = mw.language.getContentLanguage() |
local auto_magnitude_num |
local auto_magnitude_num |
local min_magnitude_num |
local min_magnitude_num |
local magnitude = args.magnitude |
local magnitude = args.magnitude |
local min_magnitude = args.min_magnitude |
local min_magnitude = args.min_magnitude |
local purge = args.purge |
local purge = args.purge |
-- Add a purge link if something (usually "yes") is entered into the purge parameter |
-- Add a purge link if something (usually "yes") is entered into the purge parameter |
if purge then |
if purge then |
purge = ' <span class="plainlinks">([' .. mw.title.getCurrentTitle():fullUrl('action=purge') .. ' purge])</span>' |
purge = ' <span class="plainlinks">([' .. mw.title.getCurrentTitle():fullUrl('action=purge') .. ' purge])</span>' |
else |
else |
purge = '' |
purge = '' |
end |
end |
-- Check that the entered timestamp is valid. If it isn't, then give an error message. |
-- Check that the entered timestamp is valid. If it isn't, then give an error message. |
local success, inputTime = pcall( lang.formatDate, lang, 'xnU', args[1] ) |
local success, inputTime = pcall( lang.formatDate, lang, 'xnU', args[1] ) |
if not success then |
if not success then |
return '<strong class="error">Error: first parameter cannot be parsed as a date or time.</strong>' |
return '<strong class="error">Error: first parameter cannot be parsed as a date or time.</strong>' |
end |
end |
-- Store the difference between the current time and the inputted time, as well as its absolute value. |
-- Store the difference between the current time and the inputted time, as well as its absolute value. |
local timeDiff = lang:formatDate( 'xnU' ) - inputTime |
local timeDiff = lang:formatDate( 'xnU' ) - inputTime |
local absTimeDiff = math.abs( timeDiff ) |
local absTimeDiff = math.abs( timeDiff ) |
if magnitude then |
if magnitude then |
auto_magnitude_num = 0 |
auto_magnitude_num = 0 |
min_magnitude_num = timeText[magnitude] |
min_magnitude_num = timeText[magnitude] |
else |
else |
-- Calculate the appropriate unit of time if it was not specified as an argument. |
-- Calculate the appropriate unit of time if it was not specified as an argument. |
local autoMagnitudeData = { |
local autoMagnitudeData = { |
{ factor = 2, amn = 31557600 }, |
{ factor = 2, amn = 31557600 }, |
{ factor = 2, amn = 2629800 }, |
{ factor = 2, amn = 2629800 }, |
{ factor = 2, amn = 86400 }, |
{ factor = 2, amn = 86400 }, |
{ factor = 2, amn = 3600 }, |
{ factor = 2, amn = 3600 }, |
{ factor = 2, amn = 60 } |
{ factor = 2, amn = 60 } |
} |
} |
for _, t in ipairs( autoMagnitudeData ) do |
for _, t in ipairs( autoMagnitudeData ) do |
if absTimeDiff / t.amn >= t.factor then |
if absTimeDiff / t.amn >= t.factor then |
auto_magnitude_num = t.amn |
auto_magnitude_num = t.amn |
break |
break |
end |
end |
end |
end |
auto_magnitude_num = auto_magnitude_num or 1 |
auto_magnitude_num = auto_magnitude_num or 1 |
if min_magnitude then |
if min_magnitude then |
min_magnitude_num = timeText[min_magnitude] |
min_magnitude_num = timeText[min_magnitude] |
else |
else |
min_magnitude_num = -1 |
min_magnitude_num = -1 |
end |
end |
end |
end |
if not min_magnitude_num then |
if not min_magnitude_num then |
-- Default to seconds if an invalid magnitude is entered. |
-- Default to seconds if an invalid magnitude is entered. |
min_magnitude_num = 1 |
min_magnitude_num = 1 |
end |
end |
local result_num |
local result_num |
local magnitude_num = math.max( min_magnitude_num, auto_magnitude_num ) |
local magnitude_num = math.max( min_magnitude_num, auto_magnitude_num ) |
local unit = timeUnits[magnitude_num].unit |
local unit = timeUnits[magnitude_num].unit |
if unit and absTimeDiff >= 864000 then |
if unit and absTimeDiff >= 864000 then |
local Date = require('Module:Date')._Date |
local Date = require('Module:Date')._Date |
local input = lang:formatDate('Y-m-d H:i:s', args[1]) -- Date needs a clean date |
local input = lang:formatDate('Y-m-d H:i:s', args[1]) -- Date needs a clean date |
input = Date(input) |
input = Date(input) |
if input then |
if input then |
local id |
local id |
if input.hour == 0 and input.minute == 0 then |
if input.hour == 0 and input.minute == 0 then |
id = 'currentdate' |
id = 'currentdate' |
else |
else |
id = 'currentdatetime' |
id = 'currentdatetime' |
end |
end |
result_num = (Date(id) - input):age(unit) |
result_num = (Date(id) - input):age(unit) |
end |
end |
end |
end |
result_num = result_num or math.floor ( absTimeDiff / magnitude_num ) |
result_num = result_num or math.floor ( absTimeDiff / magnitude_num ) |
local punctuation_key, suffix |
local punctuation_key, suffix |
if timeDiff >= 0 then -- Past |
if timeDiff >= 0 then -- Past |
if result_num == 1 then |
if result_num == 1 then |
punctuation_key = 1 |
punctuation_key = 1 |
else |
else |
punctuation_key = 2 |
punctuation_key = 2 |
end |
end |
if args.ago == '' then |
if args.ago == '' then |
suffix = '' |
suffix = '' |
else |
else |
suffix = ' ' .. (args.ago or 'ago') |
suffix = ' ' .. (args.ago or 'ago') |
end |
end |
else -- Future |
else -- Future |
if args.ago == '' then |
if args.ago == '' then |
suffix = '' |
suffix = '' |
if result_num == 1 then |
if result_num == 1 then |
punctuation_key = 1 |
punctuation_key = 1 |
else |
else |
punctuation_key = 2 |
punctuation_key = 2 |
end |
end |
else |
else |
suffix = ' time' |
suffix = ' time' |
if result_num == 1 then |
if result_num == 1 then |
punctuation_key = 3 |
punctuation_key = 3 |
else |
else |
punctuation_key = 4 |
punctuation_key = 4 |
end |
end |
end |
end |
end |
end |
local result_unit = timeUnits[ magnitude_num ][ punctuation_key ] |
local result_unit = timeUnits[ magnitude_num ][ punctuation_key ] |
-- Convert numerals to words if appropriate. |
-- Convert numerals to words if appropriate. |
local spell_out = args.spellout |
local spell_out = args.spellout |
local spell_out_max = tonumber(args.spelloutmax) |
local spell_out_max = tonumber(args.spelloutmax) |
local result_num_text |
local result_num_text |
if spell_out and ( |
if spell_out and ( |
( spell_out == 'auto' and 1 <= result_num and result_num <= 9 and result_num <= ( spell_out_max or 9 ) ) or |
( spell_out == 'auto' and 1 <= result_num and result_num <= 9 and result_num <= ( spell_out_max or 9 ) ) or |
( yesno( spell_out ) and 1 <= result_num and result_num <= 100 and result_num <= ( spell_out_max or 100 ) ) |
( yesno( spell_out ) and 1 <= result_num and result_num <= 100 and result_num <= ( spell_out_max or 100 ) ) |
) |
) |
then |
then |
result_num_text = numberSpell( result_num ) |
result_num_text = numberSpell( result_num ) |
else |
else |
result_num_text = tostring( result_num ) |
result_num_text = tostring( result_num ) |
end |
end |
-- numeric or string |
-- numeric or string |
local numeric_out = args.numeric |
local numeric_out = args.numeric |
local result = "" |
local result = "" |
if numeric_out then |
if numeric_out then |
result = tostring( result_num ) |
result = tostring( result_num ) |
else |
else |
result = result_num_text .. ' ' .. result_unit .. suffix -- Spaces for suffix have been added in earlier. |
result = result_num_text .. ' ' .. result_unit .. suffix -- Spaces for suffix have been added in earlier. |
end |
end |
return result .. purge |
return result .. purge |
end |
end |
function p.main( frame ) |
function p.main( frame ) |
local args = require( 'Module:Arguments' ).getArgs( frame, { |
local args = require( 'Module:Arguments' ).getArgs( frame, { |
valueFunc = function( k, v ) |
valueFunc = function( k, v ) |
if v then |
if v then |
v = v:match( '^%s*(.-)%s*$' ) -- Trim whitespace. |
v = v:match( '^%s*(.-)%s*$' ) -- Trim whitespace. |
if k == 'ago' or v ~= '' then |
if k == 'ago' or v ~= '' then |
return v |
return v |
end |
end |
end |
end |
return nil |
return nil |
end, |
end, |
wrappers = 'Template:Time ago' |
wrappers = 'Template:Time ago' |
}) |
}) |
return p._main( args ) |
return p._main( args ) |
end |
end |
return p |
return p |