From 36f13922d22becf3b543bc026833b3efc6c496f5 Mon Sep 17 00:00:00 2001 From: Chandragupt Singh Date: Sat, 7 Feb 2026 18:31:23 +0530 Subject: [PATCH 1/2] fix: DVB EIT start time decoding using proper BCD parsing and normalization --- src/lib_ccx/ts_tables_epg.c | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/src/lib_ccx/ts_tables_epg.c b/src/lib_ccx/ts_tables_epg.c index 95747fb5..d56dbabc 100644 --- a/src/lib_ccx/ts_tables_epg.c +++ b/src/lib_ccx/ts_tables_epg.c @@ -136,6 +136,7 @@ void EPG_DVB_calc_start_time(struct EPG_event *event, uint64_t time) if (mjd > 0) { long y, m, d, k; + struct tm timeinfo = {0}; // algo: ETSI EN 300 468 - ANNEX C y = (long)((mjd - 15078.2) / 365.25); @@ -145,10 +146,36 @@ void EPG_DVB_calc_start_time(struct EPG_event *event, uint64_t time) y = y + k + 1900; m = m - 1 - k * 12; - snprintf(event->start_time_string, sizeof(event->start_time_string), "%02ld%02ld%02ld%06" PRIu64 "+0000", y, m, d, time & 0xffffff); + timeinfo.tm_year = y - 1900; + timeinfo.tm_mon = m - 1; + timeinfo.tm_mday = d; + + // Decode BCD time (lower 24 bits: HHMMSS) + uint32_t bcd = (uint32_t)(time & 0xFFFFFF); + + timeinfo.tm_sec = (bcd & 0x0f) + (10 * ((bcd & 0xf0) >> 4)); + + timeinfo.tm_min = ((bcd & 0x0f00) >> 8) + (10 * ((bcd & 0xf000) >> 12)); + + timeinfo.tm_hour = ((bcd & 0x0f0000) >> 16) + (10 * ((bcd & 0xf00000) >> 20)); + + timeinfo.tm_isdst = -1; + + mktime(&timeinfo); + + snprintf(event->start_time_string, + sizeof(event->start_time_string), + "%04d%02d%02d%02d%02d%02d +0000", + timeinfo.tm_year + 1900, + timeinfo.tm_mon + 1, + timeinfo.tm_mday, + timeinfo.tm_hour, + timeinfo.tm_min, + timeinfo.tm_sec); } } + // Fills event.end_time_string in XMLTV with passed DVB time + duration void EPG_DVB_calc_end_time(struct EPG_event *event, uint64_t time, uint32_t duration) { From f920c16a53ede7adb3caaf6128d81754d97c8081 Mon Sep 17 00:00:00 2001 From: Chandragupt Singh Date: Sun, 8 Feb 2026 00:31:08 +0530 Subject: [PATCH 2/2] docs: add changelog entry --- docs/CHANGES.TXT | 1 + src/lib_ccx/ts_tables_epg.c | 19 +++++++++---------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/docs/CHANGES.TXT b/docs/CHANGES.TXT index 053b01d2..71361558 100644 --- a/docs/CHANGES.TXT +++ b/docs/CHANGES.TXT @@ -1,5 +1,6 @@ 0.96.6 (unreleased) ------------------- +- Fix: DVB EIT start time BCD decoding in XMLTV output causing invalid timestamps (#1835) - New: Add Snap packaging support with Snapcraft configuration and GitHub Actions CI workflow. - Fix: Clear status line output on Linux/WSL to prevent text artifacts (#2017) - Fix: Prevent infinite loop on truncated MKV files diff --git a/src/lib_ccx/ts_tables_epg.c b/src/lib_ccx/ts_tables_epg.c index d56dbabc..79bc5817 100644 --- a/src/lib_ccx/ts_tables_epg.c +++ b/src/lib_ccx/ts_tables_epg.c @@ -147,7 +147,7 @@ void EPG_DVB_calc_start_time(struct EPG_event *event, uint64_t time) m = m - 1 - k * 12; timeinfo.tm_year = y - 1900; - timeinfo.tm_mon = m - 1; + timeinfo.tm_mon = m - 1; timeinfo.tm_mday = d; // Decode BCD time (lower 24 bits: HHMMSS) @@ -164,18 +164,17 @@ void EPG_DVB_calc_start_time(struct EPG_event *event, uint64_t time) mktime(&timeinfo); snprintf(event->start_time_string, - sizeof(event->start_time_string), - "%04d%02d%02d%02d%02d%02d +0000", - timeinfo.tm_year + 1900, - timeinfo.tm_mon + 1, - timeinfo.tm_mday, - timeinfo.tm_hour, - timeinfo.tm_min, - timeinfo.tm_sec); + sizeof(event->start_time_string), + "%04d%02d%02d%02d%02d%02d +0000", + timeinfo.tm_year + 1900, + timeinfo.tm_mon + 1, + timeinfo.tm_mday, + timeinfo.tm_hour, + timeinfo.tm_min, + timeinfo.tm_sec); } } - // Fills event.end_time_string in XMLTV with passed DVB time + duration void EPG_DVB_calc_end_time(struct EPG_event *event, uint64_t time, uint32_t duration) {