Module:Countdown2

From Wikipedia, the free encyclopedia
Jump to navigation Jump to search

--- This module powers {{tl|countdown2}}.
--
-- The module takes in two primary arguments, time and offset, and returns
-- a formatted countdown string corresponding to the duration of the countdown.
--
-- @require Module:Arguments
-- @require Module:Yesno
-- @release beta

local p = {}

-- Constants
local lang = mw.language.getContentLanguage()
local getArgs = require('Module:Arguments').getArgs
local yn = require("Module:Yesno")
local floor = math.floor
local mod = math.fmod

--- Entrypoint for the module.
--
-- @param {table} frame current frame
-- @param {table} args current arguments
-- @param {string} args.time time argument
-- @param {string} args.offset offset argument
-- @param {boolean} args.shorthand whether to use shorthand units
-- @param {number} args.precision the number of units to use
-- @param {boolean} args.purge whether to show a purge link
-- @param {string} args.style inline styles to apply to countdown text
-- @return the output wikitext
function p.main(frame, args)
	args = args or getArgs(frame)
	local timeInput = args['time'] or args[1] or error("No time string specified!")
	local offset = args['offset'] or args[2] or ''
	local shorthand = yn(args['shorthand'] == nil and 'false' or args['shorthand'], false)
	local numberOfUnitsToShow = tonumber(args['precision']) or math.huge
	local showPurgeLink = yn(args['purge'] == nil and 'true' or args['purge'])
	local timestamp = tonumber(frame:preprocess("{{#time:U|" .. timeInput .. ' ' .. offset .. "|}}"))
	local currentTime = tonumber(frame:preprocess("{{#time:U}}"))
	local time_years = floor((timestamp - currentTime) / (86400 * 365.25))
	local time_months = floor(mod((timestamp - currentTime) / (86400 * 30.4375), 12))
	local time_weeks = floor(mod((timestamp - currentTime) / (86400 * 7), 4.34821429))
	local time_days = floor(mod((timestamp - currentTime) / 86400, 7))
	local time_hours = floor(mod((timestamp - currentTime) / 3600, 24))
	local time_minutes = floor(mod((timestamp - currentTime) / 60, 60))
	local time_seconds = floor(mod((timestamp - currentTime), 60))
	local out = {}
	if shorthand then
		-- clip the first letter or two of each display
		local secondDisplay, minuteDisplay, hourDisplay, dayDisplay, weekDisplay, monthDisplay, yearDisplay
		secondDisplay = mw.ustring.sub(mw.message.new("seconds", ""):plain(), 0, 1)
		minuteDisplay = mw.ustring.sub(mw.message.new("minutes", ""):plain(), 0, 1)
		hourDisplay = mw.ustring.sub(mw.message.new("hours", ""):plain(), 0, 1)
		dayDisplay = mw.ustring.sub(mw.message.new("days", ""):plain(), 0, 1)
		weekDisplay = mw.ustring.sub(mw.message.new("weeks", ""):plain(), 0, 1)
		monthDisplay = mw.ustring.sub(mw.message.new("months", ""):plain(), 0, 2)
		yearDisplay = mw.ustring.sub(mw.message.new("years", ""):plain(), 0, 1)
		if time_years > 0 and numberOfUnitsToShow > 0 then
			table.insert(out, '<span class="countdown2-year">' .. time_years .. yearDisplay .. '</span>')
			numberOfUnitsToShow = numberOfUnitsToShow - 1
		else
			table.insert(out, '<span class="countdown2-year"></span>')
		end
		if time_months > 0 and numberOfUnitsToShow > 0 then
			table.insert(out, '<span class="countdown2-month">' .. time_months .. monthDisplay .. '</span>')
			numberOfUnitsToShow = numberOfUnitsToShow - 1
		else
			table.insert(out, '<span class="countdown2-month"></span>')
		end
		if time_weeks > 0 and numberOfUnitsToShow > 0 then
			table.insert(out, '<span class="countdown2-week">' .. time_weeks .. weekDisplay .. '</span>')
			numberOfUnitsToShow = numberOfUnitsToShow - 1
		else
			table.insert(out, '<span class="countdown2-week"></span>')
		end
		if time_days > 0 and numberOfUnitsToShow > 0 then
			table.insert(out, '<span class="countdown2-day">' .. time_days .. dayDisplay .. '</span>')
			numberOfUnitsToShow = numberOfUnitsToShow - 1
		else
			table.insert(out, '<span class="countdown2-day"></span>')
		end
		if time_hours > 0 and numberOfUnitsToShow > 0 then
			table.insert(out, '<span class="countdown2-hour">' .. time_hours .. hourDisplay .. '</span>')
			numberOfUnitsToShow = numberOfUnitsToShow - 1
		else
			table.insert(out, '<span class="countdown2-hour"></span>')
		end
		if time_minutes > 0 and numberOfUnitsToShow > 0 then
			table.insert(out, '<span class="countdown2-minute">' .. time_minutes .. minuteDisplay .. '</span>')
			numberOfUnitsToShow = numberOfUnitsToShow - 1
		else
			table.insert(out, '<span class="countdown2-minute"></span>')
		end
		if time_seconds > 0 and numberOfUnitsToShow > 0 then
			table.insert(out, '<span class="countdown2-second">' .. time_seconds .. secondDisplay .. '</span>')
			numberOfUnitsToShow = numberOfUnitsToShow - 1
		else
			table.insert(out, '<span class="countdown2-second"></span>')
		end
	else
		if time_years > 0 and numberOfUnitsToShow > 0 then
			table.insert(out, '<span class="countdown2-year">' .. mw.message.new("years", time_years):plain() .. '</span>')
			numberOfUnitsToShow = numberOfUnitsToShow - 1
		else
			table.insert(out, '<span class="countdown2-year"></span>')
		end
		if time_months > 0 and numberOfUnitsToShow > 0 then
			table.insert(out, '<span class="countdown2-month">' .. mw.message.new("months", time_months):plain() .. '</span>')
			numberOfUnitsToShow = numberOfUnitsToShow - 1
		else
			table.insert(out, '<span class="countdown2-month"></span>')
		end
		if time_weeks > 0 and numberOfUnitsToShow > 0 then
			table.insert(out, '<span class="countdown2-week">' .. mw.message.new("weeks", time_weeks):plain() .. '</span>')
			numberOfUnitsToShow = numberOfUnitsToShow - 1
		else
			table.insert(out, '<span class="countdown2-week"></span>')
		end
		if time_days > 0 and numberOfUnitsToShow > 0 then
			table.insert(out, '<span class="countdown2-day">' .. mw.message.new("days", time_days):plain() .. '</span>')
			numberOfUnitsToShow = numberOfUnitsToShow - 1
		else
			table.insert(out, '<span class="countdown2-day"></span>')
		end
		if time_hours > 0 and numberOfUnitsToShow > 0 then
			table.insert(out, '<span class="countdown2-hour">' .. mw.message.new("hours", time_hours):plain() .. '</span>')
			numberOfUnitsToShow = numberOfUnitsToShow - 1
		else
			table.insert(out, '<span class="countdown2-hour"></span>')
		end
		if time_minutes > 0 and numberOfUnitsToShow > 0 then
			table.insert(out, '<span class="countdown2-minute">' .. mw.message.new("minutes", time_minutes):plain() .. '</span>')
			numberOfUnitsToShow = numberOfUnitsToShow - 1
		else
			table.insert(out, '<span class="countdown2-minute"></span>')
		end
		if time_seconds > 0 and numberOfUnitsToShow > 0 then
			table.insert(out, '<span class="countdown2-second">' .. mw.message.new("seconds", time_seconds):plain() .. '</span>')
			numberOfUnitsToShow = numberOfUnitsToShow - 1
		else
			table.insert(out, '<span class="countdown2-second"></span>')
		end
	end
	return frame:preprocess('<span class="countdown2" data-countdown-shorthand="' .. tostring(shorthand) .. '" data-countdown-timestamp="' .. timestamp .. '" data-num-units="' .. ((tonumber(args['precision']) or math.huge) == math.huge and #out or tonumber(args['precision'])) .. '><span style="' .. (args['style'] or '') .. '">'
		.. table.concat(out, " ") .. '</span>'
		.. ((#out > 0 and showPurgeLink) and ' <span class="countdown2-purgelink plainlinks">([{{fullurl:{{FULLPAGENAMEE}}|action=purge}} update])</span>' or '') .. '</span>')
end

return p