Module:Countdown2/sandbox

--- 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 round = math.floor
local mod = math.fmod

local function isLeapYear(year)
	return mod(year, 4) == 0 and
		(mod(year, 100) ~= 0 or
			(mod(year, 400) == 0))
end

p._isLeapYear = isLeapYear

local function numberOfDaysInYear(year)
	if isLeapYear(year) then
		return 366
	else
		return 365
	end
end

local function yearIncr(timestamp)
	local date = os.date("!*t", timestamp)
	if date.month >= 3 or (date.month == 2 and date.day == 28) then
		return numberOfDaysInYear(date.year + 1)
	else
		return numberOfDaysInYear(date.year)
	end
end

local function numberOfDaysInMonth(year, month)
	if month == 9 or month == 4 or month == 6 or month == 11 then
		return 30
	elseif month == 2 then
		if isLeapYear(year) then
			return 29
		else
			return 28
		end
	else
		return 31
	end
end

local function monthIncr(timestamp)
	local date = os.date("!*t", timestamp)
	if date.day >= 28 then
		return numberOfDaysInMonth(date.year, round(mod(date.month - 1, 12) + 1) + 1)
	else
		return numberOfDaysInMonth(date.year, date.month)
	end
end

--- Entrypoint for the module.
--
-- @param {table} frame current frame
-- @param {table} args current arguments
-- @param {string} args.before text to prepend to countdown
-- @param {string} args.after text to append to countdown
-- @param {string} args.time time argument
-- @param {string} args.end what to show when the countdown is over
-- @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 atEnd = args[3] or args['end'] 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}}"))
	if timestamp - currentTime <= 0 then
		return atEnd
	end

	local dateTo = os.date("!*t", timestamp)
	local dateFrom = os.date("!*t", currentTime)

	local time_days = round((timestamp - currentTime) / 86400)
	local time_hours = round(mod((timestamp - currentTime) / 3600, 24))
	local time_minutes = round(mod((timestamp - currentTime) / 60, 60))
	local time_seconds = round(mod((timestamp - currentTime), 60))

	local time_years = 0
	while time_days - yearIncr(os.time(dateFrom)) >= 0 do
		time_years = time_years + 1
		time_days = time_days - yearIncr(os.time(dateFrom))
		dateFrom.year = dateFrom.year + 1
	end
	local time_months = 0
	while time_days - monthIncr(os.time(dateFrom)) >= 0 do
		time_months = time_months + 1
		time_days = time_days - monthIncr(os.time(dateFrom))
		dateFrom.month = dateFrom.month + 1
		if (dateFrom.month == 13) then
			dateFrom.year = dateFrom.year + 1
			dateFrom.month = 1
		end
	end
	local time_weeks = round(time_days / 7)
	time_days = time_days - time_weeks * 7

	local yearNode = mw.html.create('span')
		:addClass('countdown2-year')
	local monthNode = mw.html.create('span')
		:addClass('countdown2-month')
	local weekNode = mw.html.create('span')
		:addClass('countdown2-week')
	local dayNode = mw.html.create('span')
		:addClass('countdown2-day')
	local hourNode = mw.html.create('span')
		:addClass('countdown2-hour')
	local minuteNode = mw.html.create('span')
		:addClass('countdown2-minute')
	local secondNode = mw.html.create('span')
		:addClass('countdown2-second')
	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(frame:preprocess(mw.message.new("seconds", ""):plain()), 0, 1)
		minuteDisplay = mw.ustring.sub(frame:preprocess(mw.message.new("minutes", ""):plain()), 0, 1)
		hourDisplay = mw.ustring.sub(frame:preprocess(mw.message.new("hours", ""):plain()), 0, 1)
		dayDisplay = mw.ustring.sub(frame:preprocess(mw.message.new("days", ""):plain()), 0, 1)
		weekDisplay = mw.ustring.sub(frame:preprocess(mw.message.new("weeks", ""):plain()), 0, 1)
		monthDisplay = mw.ustring.sub(frame:preprocess(mw.message.new("months", ""):plain()), 0, 2)
		yearDisplay = mw.ustring.sub(frame:preprocess(mw.message.new("years", ""):plain()), 0, 1)

		yearNode:wikitext( time_years .. yearDisplay ):done()
		monthNode:wikitext( time_months .. monthDisplay ):done()
		weekNode:wikitext( time_weeks .. weekDisplay ):done()
		dayNode:wikitext( time_days .. dayDisplay ):done()
		hourNode:wikitext( time_hours .. hourDisplay ):done()
		minuteNode:wikitext( time_minutes .. minuteDisplay ):done()
		secondNode:wikitext( time_seconds .. secondDisplay ):done()
	else
		yearNode:wikitext( mw.message.new("years", time_years):plain() )
		monthNode:wikitext( mw.message.new("months", time_months):plain() )
		weekNode:wikitext( mw.message.new("weeks", time_weeks):plain() )
		dayNode:wikitext( mw.message.new("days", time_days):plain() )
		hourNode:wikitext( mw.message.new("hours", time_hours):plain() )
		minuteNode:wikitext( mw.message.new("minutes", time_minutes):plain() )
		secondNode:wikitext( mw.message.new("seconds", time_seconds):plain() )
	end
	if time_years > 0 and numberOfUnitsToShow > 0 then
		numberOfUnitsToShow = numberOfUnitsToShow - 1
	else
		yearNode:css({ display = 'none' })
	end
	if time_months > 0 and numberOfUnitsToShow > 0 then
		numberOfUnitsToShow = numberOfUnitsToShow - 1
	else
		monthNode:css({ display = 'none' })
	end
	if time_weeks > 0 and numberOfUnitsToShow > 0 then
		numberOfUnitsToShow = numberOfUnitsToShow - 1
	else
		weekNode:css({ display = 'none' })
	end
	if time_days > 0 and numberOfUnitsToShow > 0 then
		numberOfUnitsToShow = numberOfUnitsToShow - 1
	else
		dayNode:css({ display = 'none' })
	end
	if time_hours > 0 and numberOfUnitsToShow > 0 then
		numberOfUnitsToShow = numberOfUnitsToShow - 1
	else
		hourNode:css({ display = 'none' })
	end
	if time_minutes > 0 and numberOfUnitsToShow > 0 then
		numberOfUnitsToShow = numberOfUnitsToShow - 1
	else
		minuteNode:css({ display = 'none' })
	end
	if time_seconds > 0 and numberOfUnitsToShow > 0 then
	else
		secondNode:css({ display = 'none' })
	end
	table.insert(out, tostring( yearNode ))
	table.insert(out, tostring( monthNode ))
	table.insert(out, tostring( weekNode ))
	table.insert(out, tostring( dayNode ))
	table.insert(out, tostring( hourNode ))
	table.insert(out, tostring( minuteNode ))
	table.insert(out, tostring( secondNode ))

	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 class="countdown2-before">' .. (args['before'] or '') .. '</span> <span class="countdown2-countdown" style="' .. (args['style'] or '') .. '">'
		.. table.concat(out, " ") .. '</span> <span class="countdown2-after">' .. (args['after'] or '') .. "</span>"
		.. ((#out > 0 and showPurgeLink) and '<span class="countdown2-purgelink plainlinks"> ([{{fullurl:{{FULLPAGENAMEE}}|action=purge}} update])</span>' or '') .. '<span class="countdown2-end" style="display:none;">' .. atEnd .. '</span></span>')
end

return p

Content Disclaimer

Informasi ini disarikan dari Wikipedia dan disajikan kembali untuk tujuan edukasi. Konten tersedia di bawah lisensi CC BY-SA 3.0. Kami tidak bertanggung jawab atas ketidakakuratan data yang bersumber dari kontribusi publik tersebut.

  1. The information displayed on this website is sourced in part or in whole from Wikipedia and has been adapted for the purpose of restating it. We strive to provide accurate and relevant information, however:
  2. There is no guarantee of absolute accuracy. Wikipedia is an open, collaborative project that can be edited by anyone, so information is subject to change.
  3. It is not intended to constitute professional advice. The content displayed is for informational and educational purposes only. For important decisions (e.g., medical, legal, or financial), please consult a professional.
  4. Content copyright. Wikipedia is licensed under the Creative Commons Attribution-ShareAlike License (CC BY-SA). This means that content may be reused with appropriate attribution and shared under a similar license.
  5. Responsible use. Any risk arising from the use of information from this website is entirely the responsibility of the user.