Index: trunk/BNC/src/RTCM3/RTCM3coDecoder.cpp
===================================================================
--- trunk/BNC/src/RTCM3/RTCM3coDecoder.cpp	(revision 11057)
+++ trunk/BNC/src/RTCM3/RTCM3coDecoder.cpp	(revision 11058)
@@ -1132,4 +1132,11 @@
   // Set _lastTime close to currentTime
   // ----------------------------------
+  if (_type == IGSssr) {
+    if      (epoSecGPS  != -1) _igsRefEpoSec = epoSecGPS;
+    else if (epoSecGal  != -1) _igsRefEpoSec = epoSecGal;
+    else if (epoSecQzss != -1) _igsRefEpoSec = epoSecQzss;
+    else if (epoSecSbas != -1) _igsRefEpoSec = epoSecSbas;
+  }
+
   if      (epoSecGPS != -1) {
     _lastTime.set(currentWeek, epoSecGPS);
@@ -1137,10 +1144,28 @@
   else if (epoSecGlo != -1) {
     QDate date = dateAndTimeFromGPSweek(currentTime.gpsw(), currentTime.gpssec()).date();
+    double leap = gnumleap(date.year(), date.month(), date.day());
     // IGS-SSR: the SSR Epoch Time (IDF003, 20 bit) is given in one continuous
     // time scale for all GNSS, i.e. GPS seconds of week also for GLONASS
-    // (IGS SSR v1.00) - no conversion
+    // (IGS SSR v1.00) - no conversion. Old encoders (e.g. BNC before
+    // 2026-09-30) wrote UTC seconds of day instead: recognised by comparison
+    // with the GPS/Galileo epoch of the same stream and converted, with a
+    // warning, during a transition period.
+    if (_type == IGSssr && _igsRefEpoSec >= 0.0 &&
+        igsLegacyEpoch(epoSecGlo, fmod(_igsRefEpoSec - leap + 7 * 86400.0, 86400.0), 86400.0)) {
+      double sow = floor(_igsRefEpoSec / 86400.0) * 86400.0 + epoSecGlo + leap;
+      if      (sow - _igsRefEpoSec >  43200.0) sow -= 86400.0;
+      else if (_igsRefEpoSec - sow >  43200.0) sow += 86400.0;
+      epoSecGlo = sow;
+      bncTime& warned = _legacyEpochWarned['R'];
+      if (!warned.valid() || currentTime - warned >= 3600.0) {
+        warned = currentTime;
+        emit newMessage(_staID.toLatin1() + ": IGS-SSR GLONASS epoch time in outdated convention "
+                        "(UTC seconds of day instead of GPS seconds of week, IGS SSR v1.00 IDF003) "
+                        "detected and converted - the SSR encoder should be updated", true);
+      }
+    }
     if (_type == RTCMssr || _type == RTCMnewssr) {
       // Same GLONASS epoch wire convention (UTC+3h) as RTCMssr
-      epoSecGlo = epoSecGlo - 3 * 3600 + gnumleap(date.year(), date.month(), date.day());
+      epoSecGlo = epoSecGlo - 3 * 3600 + leap;
     }
     _lastTime.set(currentWeek, epoSecGlo);
@@ -1156,6 +1181,19 @@
   }
   else if (epoSecBds != -1) {
-    // RTCM-SSR: BDT; IGS-SSR: GPS time scale for all GNSS (IDF003)
-    if (_type != IGSssr) {
+    // RTCM-SSR: BDT; IGS-SSR: GPS time scale for all GNSS (IDF003). Old
+    // IGS-SSR encoders wrote BDT: recognised and converted as for GLONASS.
+    bool bdt = (_type != IGSssr);
+    if (_type == IGSssr && _igsRefEpoSec >= 0.0 &&
+        igsLegacyEpoch(epoSecBds, fmod(_igsRefEpoSec - 14.0 + 604800.0, 604800.0), 604800.0)) {
+      bdt = true;
+      bncTime& warned = _legacyEpochWarned['C'];
+      if (!warned.valid() || currentTime - warned >= 3600.0) {
+        warned = currentTime;
+        emit newMessage(_staID.toLatin1() + ": IGS-SSR BDS epoch time in outdated convention "
+                        "(BDT instead of GPS seconds of week, IGS SSR v1.00 IDF003) "
+                        "detected and converted - the SSR encoder should be updated", true);
+      }
+    }
+    if (bdt) {
       epoSecBds += 14.0;
       if (epoSecBds > 604800.0) {
@@ -1182,4 +1220,18 @@
     }
   }
+}
+
+// IGS-SSR: true if value (seconds, periodic with period) matches the epoch
+// expected in the outdated convention (legacyRef) better than the GPS time
+// reference of the stream, within the spread of epochs of one update cycle
+////////////////////////////////////////////////////////////////////////////
+bool RTCM3coDecoder::igsLegacyEpoch(double value, double legacyRef, double period) const {
+  auto dist = [period](double a, double b) {
+    double d = fmod(fabs(a - b), period);
+    return std::min(d, period - d);
+  };
+  double dSpec   = dist(value, fmod(_igsRefEpoSec, period));
+  double dLegacy = dist(value, legacyRef);
+  return dLegacy < dSpec && dLegacy <= 30.0;
 }
 
