Module:Date2

-- Wrapper for Module:Date with extra methods for moment.js-esque manipulation -- Note: Currently only supports the date component and not the time component (use Module:Date for that)

local p = {}

local _ModuleDate = require('Module:Date') -- Base date module

local _Date = _ModuleDate._Date

function ordinal(n) local today = os.date('!*t') if today.month==4 and today.day==1 then local ords = {'th','st','nd','rd'} local o = ords[math.random(1,#ords)] return n .. '' .. o .. ' '   else local x = n % 100 if x>10 and x<14 then return n .. 'th' else x = x % 10 if x==1 then return n .. 'st' elseif x==2 then return n .. 'nd' elseif x==3 then return n .. 'rd' else return n .. 'th' end end end end

p.lengthOfMonth = function(m,y) if y==nil then return _ModuleDate._days_in_month(2019,m) -- a common year else return _ModuleDate._days_in_month(y,m) end end

local meta = { __index = function(t,k) local methods = { toStr = function(t,opt) local d = t._d if opt==nil then return d:text('%B') .. ' ' .. ordinal(tonumber(d:text('%-d'))) .. ', ' .. d:text('%Y') elseif opt=='monthyear' then return d:text('%B %Y') elseif opt=='short' then return d:text('%m/%d/%Y') --American format rip elseif opt=='ISO' then -- alias for ymd return d:text('ymd') elseif opt=='month' then return d:text('%B') elseif opt=='monthpageheading' then return d:text('%A') .. ', ' .. d:text('%B') .. ' ' .. ordinal(tonumber(d:text('%-d'))) .. ', ' .. d:text('%Y') else return d:text(opt) end end, weekday = function(t) -- numerical weekday; Sunday = 1, Saturday = 7 return tonumber(t._d:text('%w'))+1 end, nextMonth = function(t) local d = t._d + '1 month' t._d = _Date(d.year,d.month,1) return t           end, prevMonth = function(t) local d = t._d - '1 month' t._d = _Date(d.year,d.month,1) return t           end, beginMonth = function(t) t._d = _Date(t._d.year,t._d.month,1) return t           end, beginYear = function(t) t._d = _Date(t._d.year,1,1) return t           end, nextDay = function(t) t._d = t._d + 1 return t           end, prevDay = function(t) t._d = t._d - 1 return t           end, nextYear = function(t) t._d = _Date(t._d.year+1,1,1) return t           end, copy = function(t) return p(t._d) end }       if k=='year' then return t._d.year elseif k=='month' then return t._d.month elseif k=='day' then return t._d.day else return methods[k] end end, __newindex = function(t,k,v) if k=='year' then t._d = _Date(v,t._d.month,t._d.day) elseif k=='month' then t._d = _Date(t._d.year,v,t._d.day) elseif k=='day' then t._d = _Date(t._d.year,t._d.month,v) else rawset(t,k,v) end end, __lt = function(a,b) if a._d < b._d then return true else return false end end, __eq = function(a,b) if a._d == b._d then return true else return false end end }

local constructor = { __call = function(dummy,y,m,d) local t = {} if type(y)=='table' then t._d = _Date(y.year,y.month,y.day) else t._d = _Date(y,m,d) end setmetatable(t, meta) return t   end }

setmetatable(p, constructor)

p.monthFromName = function(name) return tonumber(_Date('1 ' .. name .. ' 2019'):text('%-m')) -- 2019 is a dummy year end

p.fromMonthYearName = function(name) return p(_Date('1 ' .. name)) end

return p