diff --git a/core/base/CbmDigitize.h b/core/base/CbmDigitize.h
index 207ab68d51e3195d84319dd7307fa2f4dc2fecf5..0ba33d2fe35de38f1e370047c8162f79f1b5f498 100644
--- a/core/base/CbmDigitize.h
+++ b/core/base/CbmDigitize.h
@@ -210,22 +210,28 @@ public:
 
   // --------------------------------------------------------------------------
   /** @brief Send a digi and the corresponding match object to the DAQ
+     ** @param time  Global time of the digi
      ** @param digi  Pointer to digi object (template parameter)
      ** @param match Pointer to match object
      **
+     ** Time is passed as a seperate parameter because the global time might
+     ** be too large for some digi classes to store internally. So digis are not
+     ** required to have a valid timestamp at this point. Later on when the
+     ** time slices are known, the timestamp is overwritten with the relative time
+     ** to the beginning of the time slice.
+     **
      ** TODO: The interface should be unique pointers, meaning
      ** that the digitisers have to create objects by unique pointers
      ** from the start.
      **/
-  void SendData(Digi* digi, CbmMatch* match = nullptr)
+  void SendData(Double_t time, Digi* digi, CbmMatch* match = nullptr)
   {
     std::unique_ptr<Digi> tmpDigi(digi);
     std::unique_ptr<CbmMatch> tmpMatch(match);
-    fDaqBuffer.insert(make_pair(digi->GetTime(), std::make_pair(std::move(tmpDigi), std::move(tmpMatch))));
+    fDaqBuffer.insert(make_pair(time, std::make_pair(std::move(tmpDigi), std::move(tmpMatch))));
   }
   // --------------------------------------------------------------------------
 
-
 private:
   TString fBranchName             = "";       ///< Output branch name
   std::vector<Digi>* fDigis       = nullptr;  //! Output array (Digi)
@@ -268,6 +274,7 @@ private:
       checkMinTime = kFALSE;
       checkMaxTime = checkLimit;
       tMax         = fillTime;
+      tMin         = 0;  // Do not make digi time relative for these types of time slices.
     }
     else {
       LOG(fatal) << GetName() << ": Unknown time-slice type!";
@@ -294,8 +301,11 @@ private:
       // manual removal from the source vector. There might be a more
       // elegant way.
       assert(fDigis);
-      assert(it->second.first);
-      fDigis->push_back(*(it->second.first));
+      Double_t globalTime      = it->first;
+      std::unique_ptr<Digi>& d = it->second.first;
+      assert(d);
+      d->SetTime(globalTime - tMin);
+      fDigis->push_back(*d);
       if (fCreateMatches) {
         assert(fMatches);
         assert(it->second.second);
diff --git a/core/data/mvd/CbmMvdDigi.h b/core/data/mvd/CbmMvdDigi.h
index 279cb0c329c001615de16a5e9acc74207a54b797..e7e5525f1c9d7ce67e63d9e3f563fb5d81de1ea8 100644
--- a/core/data/mvd/CbmMvdDigi.h
+++ b/core/data/mvd/CbmMvdDigi.h
@@ -80,6 +80,7 @@ public:
   void SetFlag(Int_t flag) { fDigiFlag = flag; }
   void SetFrameNr(Int_t frame) { fFrameNumber = frame; };
   void SetRefId(Int_t refId) { fRefId = refId; }
+  void SetTime(Double_t time) { fDigiTime = time; }
 
 private:
   Float_t fCharge;
diff --git a/core/data/sts/CbmStsDigi.h b/core/data/sts/CbmStsDigi.h
index 43d6be737588596b6f2cea9dfee89765ed8980c0..baab836131a76689182ff0d86d3f4837e2bdc78c 100644
--- a/core/data/sts/CbmStsDigi.h
+++ b/core/data/sts/CbmStsDigi.h
@@ -20,6 +20,7 @@
 #include <boost/serialization/access.hpp>
 #include <boost/serialization/base_object.hpp>
 
+#include <cassert>
 #include <string>  // for string
 
 /** @class CbmStsDigi
@@ -111,7 +112,12 @@ public:
   /** Update Time of measurement
    ** @param New Time [ns]
    **/
-  void SetTime(Double_t dNewTime) { fTime = dNewTime; }
+  void SetTime(Double_t dNewTime)
+  {
+    // Future versions of StsDigi won't be able to store negative timestamps.
+    assert(dNewTime >= 0);
+    fTime = dNewTime;
+  }
 
 
   /** String output **/
diff --git a/mvd/CbmMvdDigitizer.cxx b/mvd/CbmMvdDigitizer.cxx
index abd8fbc7f511e4e26f18f6d27cf031164cb50296..5e046b420aab75a59d68148ca3c65ad51ba3d8a7 100644
--- a/mvd/CbmMvdDigitizer.cxx
+++ b/mvd/CbmMvdDigitizer.cxx
@@ -151,7 +151,7 @@ void CbmMvdDigitizer::Exec(Option_t* /*opt*/)
       fMatchVect.push_back(match1);
 
       //digi1->SetMatch(match1);
-      SendData(digi1, match1);
+      SendData(digi1->GetTime(), digi1, match1);
       nDigis++;
     }
 
@@ -159,13 +159,13 @@ void CbmMvdDigitizer::Exec(Option_t* /*opt*/)
     /*
    for (Int_t index = 0; index < fTmpDigi->GetEntriesFast(); index++) {
 
-     LOG(info) << "Size: " << fTmpDigi->GetEntriesFast() << ", " 
+     LOG(info) << "Size: " << fTmpDigi->GetEntriesFast() << ", "
                << fTmpDigi->GetEntries();
- 
+
      CbmMvdDigi* digi = dynamic_cast<CbmMvdDigi*>(fTmpDigi->Remove(fTmpDigi->At(index)));
      digi->Print();
      fDigiVect.push_back(digi);
-        
+
      CbmMatch* match = dynamic_cast<CbmMatch*>(fTmpMatch->Remove(fTmpMatch->At(index)));
      match->Print();
      fMatchVect.push_back(match);
diff --git a/sim/detectors/much/CbmMuchDigitizeGem.cxx b/sim/detectors/much/CbmMuchDigitizeGem.cxx
index 0b74c91bf6f5a9439bd45c92be2e3a475384adb6..8dee1a47aca1f547eb392dbc8f229e88e8e4de70 100644
--- a/sim/detectors/much/CbmMuchDigitizeGem.cxx
+++ b/sim/detectors/much/CbmMuchDigitizeGem.cxx
@@ -648,7 +648,7 @@ void CbmMuchDigitizeGem::ReadAndRegister(Long_t eventTime)
       LOG(debug2) << GetName() << ": New digi: sector = " << CbmMuchAddress::GetSectorIndex(digi->GetAddress())
                   << " channel= " << CbmMuchAddress::GetChannelIndex(digi->GetAddress());
 
-      SendData(digi, digiMatch);
+      SendData(digi->GetTime(), digi, digiMatch);
       fNofDigis++;
     }
   }
diff --git a/sim/detectors/psd/CbmPsdSimpleDigitizer.cxx b/sim/detectors/psd/CbmPsdSimpleDigitizer.cxx
index 54fc20fddd846083f97c6fd6b80ac1bcbeb7cf52..20189379d7fa30fb67e41820db06a2a03127001d 100644
--- a/sim/detectors/psd/CbmPsdSimpleDigitizer.cxx
+++ b/sim/detectors/psd/CbmPsdSimpleDigitizer.cxx
@@ -136,10 +136,9 @@ void CbmPsdSimpleDigitizer::Exec(Option_t*)
     Double_t eLossSmeared    = eLossMIPSmeared * 0.005;
     Double_t eNoise          = gRandom->Gaus(0, 15) / 50. * 0.005;
     eLossSmeared += eNoise;
-    // The digi time is set to MC point time [relative to event start] + Event Start time
     CbmPsdDigi* digi =
       new CbmPsdDigi(entry.second.GetAddress(), entry.second.GetTime() + fCurrentEventTime, eLossSmeared);
-    SendData(digi);
+    SendData(digi->GetTime(), digi);
     nDigis++;
     LOG(debug1) << fName << ": Digi " << nDigis << " Time " << entry.second.GetTime() + fCurrentEventTime << " Section "
                 << entry.second.GetSectionID() << " Module " << entry.second.GetModuleID() << " energy "
diff --git a/sim/detectors/rich/CbmRichDigitizer.cxx b/sim/detectors/rich/CbmRichDigitizer.cxx
index 2278c49e4c6918e117ad9b1119116ec723a3842c..d9319dce9839e5dbc83f9d383b8a117cc41771ed 100644
--- a/sim/detectors/rich/CbmRichDigitizer.cxx
+++ b/sim/detectors/rich/CbmRichDigitizer.cxx
@@ -292,9 +292,9 @@ Int_t CbmRichDigitizer::AddDigisToOutputArray()
     CbmMatch* digiMatch = new CbmMatch(*dm.second.second);
     digi->SetTime(dm.second.first->GetTime());
     //SendDigi(digi, digiMatch);
-    if (fCreateMatches) SendData(digi, digiMatch);
+    if (fCreateMatches) SendData(digi->GetTime(), digi, digiMatch);
     else
-      SendData(digi);
+      SendData(digi->GetTime(), digi);
     nofDigis++;
   }  //# digis in map
 
diff --git a/sim/detectors/sts/CbmStsDigitize.cxx b/sim/detectors/sts/CbmStsDigitize.cxx
index 976eb973b7583e7745f3c29ed828e807d7df826c..8509a08e1c4c8a703daa44e8aa574a1bcd3b76ed 100644
--- a/sim/detectors/sts/CbmStsDigitize.cxx
+++ b/sim/detectors/sts/CbmStsDigitize.cxx
@@ -150,19 +150,21 @@ string CbmStsDigitize::BufferStatus() const
 // -----   Create a digi object   ------------------------------------------
 void CbmStsDigitize::CreateDigi(Int_t address, UShort_t channel, Long64_t time, UShort_t adc, const CbmMatch& match)
 {
+  assert(time >= 0);
 
   // Update times of first and last digi
   fTimeDigiFirst = fNofDigis ? TMath::Min(fTimeDigiFirst, Double_t(time)) : time;
   fTimeDigiLast  = TMath::Max(fTimeDigiLast, Double_t(time));
 
   // Create digi and (if required) match and send them to DAQ
-  CbmStsDigi* digi = new CbmStsDigi(address, channel, time, adc);
+  // Digi time is set later, when creating the timestamp
+  CbmStsDigi* digi = new CbmStsDigi(address, channel, 0, adc);
   if (fCreateMatches) {
     CbmMatch* digiMatch = new CbmMatch(match);
-    SendData(digi, digiMatch);
+    SendData(time, digi, digiMatch);
   }
   else
-    SendData(digi);
+    SendData(time, digi);
   fNofDigis++;
 }
 // -------------------------------------------------------------------------
diff --git a/sim/detectors/tof/CbmTofDigitize.cxx b/sim/detectors/tof/CbmTofDigitize.cxx
index 6686d182fe182c9652c3c194b0b410296684a854..c8ce975ad58758c24d07b618f502a1b64295d343 100644
--- a/sim/detectors/tof/CbmTofDigitize.cxx
+++ b/sim/detectors/tof/CbmTofDigitize.cxx
@@ -1043,7 +1043,7 @@ Bool_t CbmTofDigitize::MergeSameChanDigis()
     const Double_t dHitTot = 2.;
     CbmTofDigi* tDigi      = new CbmTofDigi(uChanUId, dHitTime, dHitTot);
     CbmMatch* tMatch       = new CbmMatch();
-    SendData(tDigi, tMatch);  // Send digi to DAQ
+    SendData(tDigi->GetTime(), tDigi, tMatch);  // Send digi to DAQ
     fiNbDigis++;
     LOG(debug) << Form("Add fake diamond digis 0x%08x mode with t = %7.3f", uChanUId, dHitTime);
     //delete tDigi;
@@ -1137,7 +1137,7 @@ Bool_t CbmTofDigitize::MergeSameChanDigis()
                       new CbmMatch(*(fStorDigi[iSmType][iSm * iNbRpc + iRpc][iNbSides * iCh + iSide][iDigi0].second));
 
                     digi->SetTime(digi->GetTime() * fdDigiTimeConvFactor + fCurrentEventTime);  // ns->ps
-                    SendData(digi, match);                                                      // Send digi to DAQ
+                    SendData(digi->GetTime(), digi, match);                                     // Send digi to DAQ
                     fiNbDigis++;
 
                     // TOF QA
@@ -1176,7 +1176,7 @@ Bool_t CbmTofDigitize::MergeSameChanDigis()
               CbmMatch* match =
                 new CbmMatch(*(fStorDigi[iSmType][iSm * iNbRpc + iRpc][iNbSides * iCh + iSide][iDigi0].second));
               digi->SetTime(digi->GetTime() * fdDigiTimeConvFactor + fCurrentEventTime);  // ns->ps
-              SendData(digi, match);                                                      // Send digi to DAQ
+              SendData(digi->GetTime(), digi, match);                                     // Send digi to DAQ
               fiNbDigis++;
 
               if (fbMonitorHistos) {
diff --git a/sim/detectors/trd/CbmTrdDigitizer.cxx b/sim/detectors/trd/CbmTrdDigitizer.cxx
index bc51eaf5e65a17a23e702cffa4aea25c44b1f368..c80773c4026797216254cc8322db2a6fc87d6df8 100644
--- a/sim/detectors/trd/CbmTrdDigitizer.cxx
+++ b/sim/detectors/trd/CbmTrdDigitizer.cxx
@@ -211,7 +211,8 @@ void CbmTrdDigitizer::Exec(Option_t*)
     //printf("  Digits[%d] %d\n", imod->first, digis->size());
     for (std::map<Int_t, pair<CbmTrdDigi*, CbmMatch*>>::iterator it = digis->begin(); it != digis->end(); it++) {
       assert(it->second.second);
-      SendData(it->second.first, it->second.second);
+      CbmTrdDigi* digi = it->second.first;
+      SendData(digi->GetTime(), digi, it->second.second);
       nDigis++;
     }  //# modules
     digis->clear();
@@ -248,7 +249,8 @@ void CbmTrdDigitizer::FlushBuffers()
     std::map<Int_t, std::pair<CbmTrdDigi*, CbmMatch*>>* digis = imod->second->GetDigiMap();
     for (std::map<Int_t, pair<CbmTrdDigi*, CbmMatch*>>::iterator it = digis->begin(); it != digis->end(); it++) {
       assert(it->second.second);
-      SendData(it->second.first, it->second.second);
+      CbmTrdDigi* digi = it->second.first;
+      SendData(digi->GetTime(), digi, it->second.second);
       nDigis++;
     }  //# modules
     digis->clear();
@@ -278,7 +280,7 @@ CbmTrdModuleSim* CbmTrdDigitizer::AddModule(Int_t detId)
  * The trd layer is again only a container for all volumes of this layer.
  * Loop over all nodes below the top node (cave). If one of
  * the nodes contains a string trd it must be TRD detector.
- * Now loop over the layers and 
+ * Now loop over the layers and
  * then over all modules of the layer to extract in the end
  * all active regions (gas) of the complete TRD. For each
  * of the gas volumes get the information about size and
diff --git a/sim/detectors/trd/CbmTrdModuleSimT.cxx b/sim/detectors/trd/CbmTrdModuleSimT.cxx
index 85901644d73a9c2f711da0d5f0bf67c0dea1043a..b21a000f0121e18fdd24f5b5ff86cff2bb0fc9ae 100644
--- a/sim/detectors/trd/CbmTrdModuleSimT.cxx
+++ b/sim/detectors/trd/CbmTrdModuleSimT.cxx
@@ -62,8 +62,8 @@ CbmTrdModuleSimT::~CbmTrdModuleSimT()
 //_________________________________________________________________________________
 Bool_t CbmTrdModuleSimT::MakeDigi(CbmTrdPoint* point, Double_t time, Bool_t TR)
 {
-  /**  
-  Steering routine for building digits out of the TRD hit for the triangular pad geometry. 
+  /**
+  Steering routine for building digits out of the TRD hit for the triangular pad geometry.
   1. Scan the amplification cells span by the track\n
   2. Build digits for each cell proportional with the projected energy on the cell\n
     2.1 Continuous distribution for ionisation\n
@@ -281,14 +281,14 @@ Bool_t CbmTrdModuleSimT::MakeDigi(CbmTrdPoint* point, Double_t time, Bool_t TR)
 //_________________________________________________________________________________
 Bool_t CbmTrdModuleSimT::ScanPadPlane(const Double_t* point, Double_t DX, Double_t ELoss, Double_t toff)
 {
-  /**  
+  /**
   The hit is expressed in local chamber coordinates, localized as follows:
     - Along the wire in the middle of the track projection on the closest wire
     - Across the wire on the closest anode.
-    
+
   The physical uncertainty along wires is given by the projection span (dx) and the energy from ionisation is proportional to the track projection length in the local chamber x-y plane. For the TR energy the proportionality to the total TR is given by the integral over the amplification cell span of a decay law with decay constant ...
-  
-  The class CbmTrdTrianglePRF is used to navigate the pad plane outward from the hit position until a threshold wrt to center is reached. The pad-row cross clusters are considered. Finally all digits are registered via AddDigi() function. 
+
+  The class CbmTrdTrianglePRF is used to navigate the pad plane outward from the hit position until a threshold wrt to center is reached. The pad-row cross clusters are considered. Finally all digits are registered via AddDigi() function.
 */
   if (VERBOSE)
     printf("        WirePlane : xy[%7.4f %7.4f] D[%7.4f] S[fC]=%7.4f "
@@ -563,7 +563,7 @@ void CbmTrdModuleSimT::AddDigi(Int_t address, Double_t* charge, Double_t time /*
 Int_t CbmTrdModuleSimT::FlushBuffer(ULong64_t time)
 {
   /** Flush time sorted digi buffer until requested moment in time. If time limit not specified flush all digits.
- *  Calculate timely interaction between digits which are produced either on different anode wires for the same particle or 
+ *  Calculate timely interaction between digits which are produced either on different anode wires for the same particle or
  * are produced by 2 particle close by. Also take into account FASP dead time and mark such digits correspondingly
  */
 
@@ -694,7 +694,7 @@ Int_t CbmTrdModuleSimT::FlushBuffer(ULong64_t time)
 
       if (VERBOSE) cout << "\t" << digi->ToString();
       digiMatch = iv->second;
-      fDigitizer->SendData(digi, digiMatch);
+      fDigitizer->SendData(digi->GetTime(), digi, digiMatch);
       n++;
       iv = fBuffer[localAddress].erase(iv);  // remove from saved buffer
     }