Module:TimeUtil

local lang = mw.getLanguage('en') local util_table = require('Module:TableUtil') local Date = require('Module:Date') local SECONDS_IN_DAY = 24 * 60 * 60

local TZLIST = { 'PST', 'CET', 'KST' }

local h = {}

function h.printDelta(delta) return delta > 0 and ('+' .. delta) or delta end

local p = {}

p.monthNumberToTri = { 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec' }

p.monthNumberToName = { 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December' }

p.monthNameToNumber = util_table.hash(p.monthNumberToName)

p.toUTC = { [true] = { PST = 7, CET = -2, KST = -9 }, [false] = { PST = 8, CET = -1, KST = -9 }, spring = { PST = 7, CET = -1, KST = -9 }, fall = { PST = 7, CET = -1, KST = -9 }, }

function p.strToTime(str) local year, month, day, hour, minute, second = string.match(str, "(%d%d%d%d)%-(%d%d)%-(%d%d) (%d%d):(%d%d):(%d%d)") return { year = year, month = month, day = day, hour = hour, min = minute, sec = second } end

function p.strToDate(str) local year, month, day = string.match(str, "(%d%d%d%d)-(%d%d)-(%d%d)") return { year = year, month = month, day = day } end

function p.strToDateStr(str) if not str then return nil end local date = str:match("(%d%d%d%d%-%d%d%-%d%d)") return date end

function p.strToTimeStr(str) if not str then return nil end return str:match('%d%d:%d%d') end

function p.strToDateFuzzy(str) local year, month, day = str:match('([%d?][%d?][%d?][%d?])-([%d?][%d?])-([%d?][%d?])') return { year = year, month = month, day = day } end

function p.isInFuture(str, intervalSeconds) if not intervalSeconds then intervalSeconds = 0 end return os.difftime(os.time(p.strToTime(str)),os.time) > intervalSeconds end

function p.dateIsInFuture(str, intervalSeconds) if not intervalSeconds then intervalSeconds = 0 end local time = p.strToDateFuzzy(str) if time.day == '??' then time.day = 31 end if time.month == '??' then time.month = 12 end return os.difftime(os.time(time),os.time) > intervalSeconds end

function p.dateIsInFutureOrNow(str, intervalSeconds) local time = p.strToDateFuzzy(str) if time.day == '??' then time.day = 31 end if time.month == '??' then time.month = 12 end return os.difftime(os.time(time),os.time) > -1 / 2 * SECONDS_IN_DAY end

function p.dateInLocal(str) local tbl = mw.html.create('span'):addClass('DateInLocal'):wikitext(lang:formatDate('Y,n,d,H,i', str)) return tostring(tbl) end

function p.dateOnlyInLocal(str) local tbl = mw.html.create('span'):addClass('DateOnlyInLocal'):wikitext(lang:formatDate('Y,n,d,H,i', str)) return tostring(tbl) end

function p.dateInLocalMatches(str) local tbl = mw.html.create('span'):addClass('DateInLocalMatches'):wikitext(lang:formatDate('Y,n,d,H,i', str)) return tostring(tbl) end

function p.timeInLocal(str) local tbl = mw.html.create('span'):addClass('TimeInLocal'):wikitext(lang:formatDate('Y,n,d,H,i', str)) return tostring(tbl) end

function p.countdown(str, args) if not args then args = {} end local i = args.i or '' local data_end = args.data_end or 'remove' local options = args.options and table.concat(args.options, ' ') or 'no-leading-zeros' local tbl = mw.html.create tbl:tag('span') :attr('data-end', data_end) :attr('data-options',options) :attr('data-toggle','.post-countdown' .. i)		:addClass('countdown') :css('display','none') :tag('span') :addClass('countdowndate') :wikitext(lang:formatDate('j F Y H:i:s', str) .. ' +0000') tbl:tag('span') :addClass('post-countdown' .. i)		:css('display','none') :wikitext(args.default or '-') return tostring(tbl) end

function p.unix(str) return lang:formatDate('U', str) end

function p.unixNumber(str) if not str then return nil end return tonumber(p.unix(str)) end

function p.age(bday) if type(bday) == 'string' then bday = p.strToDate(bday) end for k, v in pairs(bday) do		bday[k] = tonumber(v) end local now = os.date('*t') local bdaypast = now.month > bday.month or now.month == bday.month and now.day >= bday.day return now.year - bday.year - 1 + (bdaypast and 1 or 0) end

function p.getTimezones(str, init_tz, dst) if not p.toUTC[dst] then error(('Invalid timezone value of %s. Allowed values: yes, no, spring, fall.'):format(dst)) end local delta = p.toUTC[dst][init_tz] local utc = lang:formatDate('Y-m-d H:i', ('%s %s hours'):format(str, h.printDelta(delta))) local tbl = { UTC = utc } for _, v in pairs(TZLIST) do		delta = -1 * p.toUTC[dst][v] tbl[v] = lang:formatDate('Y-m-d H:i', ('%s %s hours'):format(utc, h.printDelta(delta))) end tbl.UTC = utc return tbl end

function p.strFromTable(dt, format) local str = os.date('%Y-%m-%d', os.time(dt)) if not format then return str end return lang:formatDate(format, str) end

return p