Module:Date table sorting
Appearance
![]() | This Lua module is used on approximately 45,000 pages and changes may be widely noticed. Test changes in the module's /sandbox or /testcases subpages, or in your own module sandbox. Consider discussing changes on the talk page before implementing them. |
This module implements {{Date table sorting}}. Please see the template page for documentation.
local getArgs = require('Module:Arguments').getArgs
--------------------------------------------------------------------------------
-- Dts class
--------------------------------------------------------------------------------
local Dts = {}
Dts.__index = Dts
Dts.monthsSearch = { "jan", "feb", "mar", "apr", "may", "jun", "jul", "aug", "sep", "oct", "nov", "dec" }
Dts.monthsAbr = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }
Dts.months = { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" }
function Dts.new(args)
local self = setmetatable({}, Dts)
self.format = args.format or "mdy"
self.abbr = false -- Default
if args[1] and (not args[2]) then
for _, val in pairs(mw.text.split(args[1],"[%s/-]")) do
self:annonval(val, true)
end
else
for key, val in pairs(args) do
if tonumber(key) then
self:annonval(val)
end
end
end
if args.abbr then
if args.abbr == "on" then
self.abbr=true
else
self.abbr=false
end
end
if (self.year==0) then --not valid. placeholder for no-year
self.year = nil
end
return self
end
function Dts:setmonth(raw)
if not raw then
self.month = nil
return false
end
local numbermonth = tonumber(raw)
if numbermonth and numbermonth > 0 and numbermonth < 13 then
self.month = numbermonth
return true
end
for i, mon in pairs(self.monthsSearch) do
if string.find(string.lower(raw),mon) then
self.month=i
if string.find(string.lower(raw),string.lower(self.months[i])) then
self.abbr=false
else
self.abbr=true
end
return true
end
end
return false
end
function Dts:annonval(val, dayfirst)
local numberval
if val then
numberval = tonumber(mw.text.trim(val,"%s%t,"))
end
if (not val) or (type(val)=="table") or (mw.text.trim(val)=="") then
numberval = 0
end
if not numberval then
if mw.text.trim(string.lower(val)) == "bc" then
if (not self.year) then
self.year = self.day
self.day = nil
end
if self.year then
self.year = 0 - self.year
end
else
if self:setmonth(val,dayfirst) and dayfirst and self.year and (not self.day) and (self.year > 0) and (self.year<31) then
self.day = self.year
self.year = nil
self.format = "dmy"
end
end
return
end
if self.month and (not self.day) and (numberval < 32) and (numberval > 0) then
self.day = numberval
return
end
if self.year and (not self.month) then
self.month = numberval
return
end
if (not self.year) then
self.year = numberval
return
end
end
function Dts:monthName()
if (not self.month) or (self.month < 0) or (self.month > 12) then
return ""
end
if self.abbr then
return self.monthsAbr[self.month]
else
return self.months[self.month]
end
end
function Dts:makeSortKey()
local year = self.year or os.date("*t").year
year = year > 0 and year or -10000 - year
return string.format(
"%05d-%02d-%02d-%02d%02d",
year,
self.month or 1,
self.day or 1,
0,
0
)
end
function Dts:makeDisplay()
local ret = {}
if self.day then
if self.format == "mdy" then
ret[#ret + 1] = self:monthName()
ret[#ret + 1] = ' '
ret[#ret + 1] = self.day
if self.year then
ret[#ret + 1] = ','
end
else
ret[#ret + 1] = self.day
ret[#ret + 1] = ' '
ret[#ret + 1] = self:monthName()
end
elseif self.month then
ret[#ret + 1] = self:monthName()
end
if self.year then
if self.month then
ret[#ret + 1] = ' '
end
ret[#ret + 1] = math.abs(self.year)
if self.year < 0 then
ret[#ret + 1] = ' BC'
end
end
return table.concat(ret)
end
function Dts:__tostring()
local root = mw.html.create()
root
:tag('span')
:addClass('sortkey')
:css('display', 'none')
:css('speak', 'none')
:wikitext(self:makeSortKey())
:done()
:tag('span')
:css('white-space', 'nowrap')
:wikitext(self:makeDisplay())
return tostring(root)
end
--------------------------------------------------------------------------------
-- Exports
--------------------------------------------------------------------------------
local p = {}
function p._main(args)
local dts = Dts.new(args)
return tostring(dts)
end
function p.main(frame)
local args = getArgs(frame, {
wrappers = 'Template:Dts',
removeBlanks = false
})
return p._main(args)
end
return p