diff --git a/include/DoocsProcessArray.h b/include/DoocsProcessArray.h
index 97d57a7814840bb2465d380aeedd3cadb3ff7bb3..b73c4d0e9bcd53b15526070b59d6a21b35a14f75 100644
--- a/include/DoocsProcessArray.h
+++ b/include/DoocsProcessArray.h
@@ -155,23 +155,25 @@ namespace ChimeraTK {
       this->fill_array(dataPtr, processVector.size());
       modified = true;
 
-      // Convert time stamp from version number in Unix time (seconds and microseconds).
-      // Note that epoch of std::chrono::system_time might be different from Unix time, and Unix time omits leap seconds
-      // and hence is not the duration since the epoch! We have to convert to time_t and then find out the microseconds.
-      auto timestamp = _processArray->getVersionNumber().getTime();
-      auto seconds = std::chrono::system_clock::to_time_t(timestamp);
-      auto microseconds = std::chrono::duration_cast<std::chrono::microseconds>(
-          timestamp - std::chrono::system_clock::from_time_t(seconds))
-                              .count();
-      this->set_tmstmp(seconds, microseconds);
+      // Convert time stamp from version number to DOOCS timestamp
+      doocs::Timestamp timestamp(_processArray->getVersionNumber().getTime());
+
+      // Make sure we never send out two absolute identical time stamps. If we would do so, the "watchdog" which
+      // corrects inconsistencies in ZeroMQ subscriptions between sender and subcriber cannot detect the inconsistency.
+      if(this->get_timestamp() == timestamp) {
+        timestamp += std::chrono::microseconds(1);
+      }
+
+      this->set_timestamp(timestamp);
       if(_macroPulseNumberSource) this->set_mpnum(_macroPulseNumberSource->accessData(0));
 
       // send data via ZeroMQ if enabled and if DOOCS initialisation is complete
       if(publishZMQ && ChimeraTK::DoocsAdapter::isInitialised) {
         dmsg_info info;
         memset(&info, 0, sizeof(info));
-        info.sec = seconds;
-        info.usec = microseconds;
+        auto sinceEpoch = timestamp.get_seconds_and_microseconds_since_epoch();
+        info.sec = sinceEpoch.seconds;
+        info.usec = sinceEpoch.microseconds;
         if(_macroPulseNumberSource != nullptr) {
           info.ident = _macroPulseNumberSource->accessData(0);
         }
diff --git a/include/DoocsProcessScalar.h b/include/DoocsProcessScalar.h
index bbfadeb7a4a238e85421cf95bdb9f83af581ac11..a79f8137dde72d931d83bc75bfdaf1fce754a542 100644
--- a/include/DoocsProcessScalar.h
+++ b/include/DoocsProcessScalar.h
@@ -61,13 +61,14 @@ namespace ChimeraTK {
         this->d_error(no_error);
       }
 
-      // Convert time stamp from version number in Unix time (seconds and microseconds).
-      // Note that epoch of std::chrono::system_time might be different from Unix time, and Unix time omits leap seconds
-      // and hence is not the duration since the epoch! We have to convert to time_t and then find out the microseconds.
+      // Convert time stamp from version number to DOOCS timestamp
       doocs::Timestamp timestamp(_processScalar->getVersionNumber().getTime());
-      auto sinceEpoch = timestamp.get_seconds_and_microseconds_since_epoch();
-      auto seconds = sinceEpoch.seconds;
-      auto microseconds = sinceEpoch.microseconds;
+
+      // Make sure we never send out two absolute identical time stamps. If we would do so, the "watchdog" which
+      // corrects inconsistencies in ZeroMQ subscriptions between sender and subcriber cannot detect the inconsistency.
+      if(this->get_timestamp() == timestamp) {
+        timestamp += std::chrono::microseconds(1);
+      }
 
       // update global time stamp of DOOCS, but only if our time stamp is newer
       if(get_global_timestamp() < timestamp) {
@@ -94,15 +95,16 @@ namespace ChimeraTK {
 
       // We must set the timestamp again so it is correctly attached to the variable. set_and_archive does not to it.
       // This must happen after set_and_archive, otherwise the global time stamp is taken.
-      this->set_tmstmp(seconds, microseconds);
+      this->set_timestamp(timestamp);
       if(_macroPulseNumberSource) this->set_mpnum(_macroPulseNumberSource->accessData(0));
 
       // send data via ZeroMQ if enabled and if DOOCS initialisation is complete
       if(_publishZMQ && ChimeraTK::DoocsAdapter::isInitialised) {
         dmsg_info info;
         memset(&info, 0, sizeof(info));
-        info.sec = seconds;
-        info.usec = microseconds;
+        auto sinceEpoch = timestamp.get_seconds_and_microseconds_since_epoch();
+        info.sec = sinceEpoch.seconds;
+        info.usec = sinceEpoch.microseconds;
         if(_macroPulseNumberSource != nullptr) {
           info.ident = _macroPulseNumberSource->accessData(0);
         }
diff --git a/src/DoocsIfff.cc b/src/DoocsIfff.cc
index 2feec99c2b9a822797affd0e3e4c3eb95ce7fd65..fd2869791ec6e34c09275a52eeaf76024d98b4a7 100644
--- a/src/DoocsIfff.cc
+++ b/src/DoocsIfff.cc
@@ -87,6 +87,12 @@ namespace ChimeraTK {
 
     doocs::Timestamp timestamp(_i1Value->getVersionNumber().getTime());
 
+    // Make sure we never send out two absolute identical time stamps. If we would do so, the "watchdog" which
+    // corrects inconsistencies in ZeroMQ subscriptions between sender and subcriber cannot detect the inconsistency.
+    if(this->get_timestamp() == timestamp) {
+      timestamp += std::chrono::microseconds(1);
+    }
+
     // update global time stamp of DOOCS, but only if our time stamp is newer
     if(get_global_timestamp() < timestamp) {
       set_global_timestamp(timestamp);
diff --git a/src/DoocsSpectrum.cc b/src/DoocsSpectrum.cc
index f7b42197afd54e1212a703b2aac4734a506fe4ff..b0181fff54adb6ab69bf7da1dfbcfdcf250c3743 100644
--- a/src/DoocsSpectrum.cc
+++ b/src/DoocsSpectrum.cc
@@ -148,14 +148,18 @@ namespace ChimeraTK {
     }
     _doocsSuccessfullyUpdated = true;
 
-    // Convert time stamp from version number in Unix time (seconds and microseconds).
-    // Note that epoch of std::chrono::system_time might be different from Unix time, and Unix time omits leap seconds
-    // and hence is not the duration since the epoch! We have to convert to time_t and then find out the microseconds.
-    auto timestamp = _processArray->getVersionNumber().getTime();
-    auto seconds = std::chrono::system_clock::to_time_t(timestamp);
-    auto microseconds = std::chrono::duration_cast<std::chrono::microseconds>(
-        timestamp - std::chrono::system_clock::from_time_t(seconds))
-                            .count();
+    // Convert time stamp from version number to DOOCS timestamp
+    doocs::Timestamp timestamp(_processArray->getVersionNumber().getTime());
+
+    // Make sure we never send out two absolute identical time stamps. If we would do so, the "watchdog" which
+    // corrects inconsistencies in ZeroMQ subscriptions between sender and subcriber cannot detect the inconsistency.
+    if(this->get_timestamp() == timestamp) {
+      timestamp += std::chrono::microseconds(1);
+    }
+
+    auto sinceEpoch = timestamp.get_seconds_and_microseconds_since_epoch();
+    auto seconds = sinceEpoch.seconds;
+    auto microseconds = sinceEpoch.microseconds;
 
     // set macro pulse number, buffer number and time stamp
     size_t ibuf = 0;