-- Copyright 2025 David Vazgenovich Shakaryan local epg = {} local mt = {} mt.__index = mt function epg.new() return setmetatable({channels = {}}, mt) end -- local (non-DST) offset from UTC local tz_offset do local t = os.time() tz_offset = os.time(os.date('*t', t)) - os.time(os.date('!*t', t)) end local function parse_time(str) local y, m, d, hh, mm, ss, zsign, zh, zm = str:match( '(%d%d%d%d)(%d%d)(%d%d)(%d%d)(%d%d)(%d%d) ([+-])(%d%d)(%d%d)') local dt = { year = y, month = m, day = d, hour = hh, min = mm, sec = ss, isdst = false} return os.time(dt) + tz_offset - (tonumber(zsign..zh) * 3600 + tonumber(zsign..zm) * 60) end function mt:load_xc_data(data) for _, v in ipairs(data) do local ch = v.channel:lower() local prog = { start = parse_time(v.start), stop = parse_time(v.stop), title = v.title, desc = v.desc, } if self.channels[ch] then self.channels[ch][#self.channels[ch]+1] = prog else self.channels[ch] = {prog} end end for _, progs in pairs(self.channels) do table.sort(progs, function(a, b) return a.start < b.start end) end end function mt:channel_programmes(ch) return self.channels[ch] end function mt:scheduled_programme(ch, time) local progs = self.channels[ch] if not progs then return end for _, v in ipairs(progs) do if time >= v.start and time < v.stop then return v end end end return epg