Index: /trunk/MagicSoft/Mars/Changelog
===================================================================
--- /trunk/MagicSoft/Mars/Changelog	(revision 2611)
+++ /trunk/MagicSoft/Mars/Changelog	(revision 2612)
@@ -4,4 +4,15 @@
 
                                                  -*-*- END OF LINE -*-*-
+ 2003/12/07: Thomas Bretz
+
+   * mbase/MTime.[h,cc]:
+     - added some new member function
+     - fixed wrong calculations
+     
+   * mhist/MHPixVsTime.cc, mhist/MHVsTime.cc:
+     - fixed MTime handling
+
+
+
  2003/12/05: Abelardo Moralejo
  
Index: /trunk/MagicSoft/Mars/mbase/MTime.cc
===================================================================
--- /trunk/MagicSoft/Mars/mbase/MTime.cc	(revision 2611)
+++ /trunk/MagicSoft/Mars/mbase/MTime.cc	(revision 2612)
@@ -29,4 +29,6 @@
 // A generalized MARS time stamp
 //
+// WARNING: Be carefull changing this class. It is also used in the
+//          MAGIC drive software cosy!
 //
 // Version 1:
@@ -58,4 +60,11 @@
 using namespace std;
 
+const UInt_t MTime::kHour = 3600000;         // [ms] one hour
+const UInt_t MTime::kDay  = MTime::kHour*24; // [ms] one day
+
+// --------------------------------------------------------------------------
+//
+// Return date as year(y), month(m), day(d)
+//
 void MTime::GetDate(UShort_t &y, Byte_t &m, Byte_t &d) const
 {
@@ -63,4 +72,96 @@
 }
 
+// --------------------------------------------------------------------------
+//
+// Return the time in the range [0h, 24h) = [0h0m0.000s - 23h59m59.999s]
+//
+void MTime::GetTime(Byte_t &h, Byte_t &m, Byte_t &s, UShort_t &ms) const
+{
+    Long_t tm = GetTime24();
+    ms  = tm%1000;            // [ms]
+    tm /= 1000;               // [s]
+    s   = tm%60;              // [s]
+    tm /= 60;                 // [m]
+    m   = tm%60;              // [m]
+    tm /= 60;                 // [h]
+    h   = tm;                 // [h]
+}
+
+// --------------------------------------------------------------------------
+//
+//  Return time as MJD (=JD-24000000.5)
+//
+Double_t MTime::GetMjd() const
+{
+    return fMjd+(Double_t)(fNanoSec/1e6+(Long_t)fTime)/kDay;
+}
+
+// --------------------------------------------------------------------------
+//
+// Return a time which is expressed in milliseconds since 01/01/1995 0:00h
+// This is compatible with root's definition used in gSystem->Now()
+// and TTime.
+// Note, gSystem->Now() returns local time, such that it may differ
+// from GetRootTime() (if you previously called MTime::Now())
+//
+TTime MTime::GetRootTime() const
+{
+    return (ULong_t)((GetMjd()-49718)*kDay);
+}
+
+// --------------------------------------------------------------------------
+//
+// Return a time which is expressed in seconds since 01/01/1995 0:00h
+// This is compatible with root's definition used in TAxis.
+// Note, a TAxis always displayes (automatically) given times in
+// local time (while here we return UTC) such, that you may encounter
+// strange offsets. You can get rid of this by calling:
+//    TAxis::SetTimeFormat("[your-format] %F1995-01-01 00:00:00");
+//
+Double_t MTime::GetAxisTime() const
+{
+    return (GetMjd()-49718)*kDay/1000;
+}
+
+// --------------------------------------------------------------------------
+//
+// Set a time expressed in MJD, Time of Day (eg. 23:12.779h expressed
+// in milliseconds) and a nanosecond part.
+//
+Bool_t MTime::Set(UInt_t mjd, ULong_t ms, UInt_t ns=0)
+{
+    // [d]  mjd  (eg. 52320)
+    // [ms] time (eg. 17h expressed in ms)
+    // [ns] time (ns part of time)
+
+    if (ms>kDay-1 || ns>999999)
+        return kFALSE;
+
+    const Bool_t am = ms < kHour*13; // day of sunrise?
+
+    fMjd     = am ? mjd : mjd + 1;
+    fTime    = (Long_t)(am ? ms  : ms-kDay);
+    fNanoSec = ns;
+
+    return kTRUE;
+}
+
+// --------------------------------------------------------------------------
+//
+// Set MTime to given MJD (eg. 52080.0915449892)
+//
+void MTime::SetMjd(Double_t m)
+{
+    const UInt_t   mjd  = (UInt_t)TMath::Floor(m);
+    const Double_t frac = fmod(m, 1)*kDay; // [ms] Fraction of day
+    const UInt_t   ns   = (UInt_t)fmod(frac*1e6, 1000000);
+
+    Set(mjd, (ULong_t)TMath::Floor(frac), ns);
+}
+
+// --------------------------------------------------------------------------
+//
+// Set MTime to given time and date
+//
 Bool_t MTime::Set(UShort_t y, Byte_t m, Byte_t d, Byte_t h, Byte_t min, Byte_t s, UShort_t ms, UInt_t ns)
 {
@@ -77,20 +178,47 @@
 }
 
-void MTime::SetSystemTimer(const struct timeval &tv)
-{
-    const ULong_t hor = 3600000; // One Hour in milliseconds
-
-    const UInt_t mjd = tv.tv_sec/(60*60*24) + 40587;
-    const Long_t tm  = (tv.tv_usec/1000)%(24*hor);
-
-    Set(mjd, tm, tv.tv_usec*1000);
-}
-
+// --------------------------------------------------------------------------
+//
+// Set MTime to time expressed in a 'struct timeval'
+//
+void MTime::Set(const struct timeval &tv)
+{
+    const UInt_t mjd = 1000*tv.tv_sec/kDay + 40587;
+    const Long_t tm  = tv.tv_sec%(24*3600)*1000 + tv.tv_usec/1000;
+    const UInt_t ms  = tv.tv_usec%1000;
+
+    Set(mjd, tm, ms*1000);
+}
+
+// --------------------------------------------------------------------------
+//
+// Set MTime to time expressed as in CT1 PreProc files
+//
+void MTime::SetCT1Time(UInt_t mjd, UInt_t t1, UInt_t t0)
+{
+    // int   isecs_since_midday; // seconds passed since midday before sunset (JD of run start)
+    // int   isecfrac_200ns;     // fractional part of isecs_since_midday
+    // fTime->SetTime(isecfrac_200ns, isecs_since_midday);
+    fNanoSec         = (200*t1)%1000000;
+    const ULong_t ms = (200*t1)/1000000 + t0+12*kHour;
+
+    fTime = (Long_t)(ms<13*kHour ? ms : ms-kDay);
+
+    fMjd = mjd+1;
+}
+
+// --------------------------------------------------------------------------
+//
+// Set the time to the current system time. The timezone is ignored.
+// If everything is set correctly you'll get UTC.
+//
 void MTime::Now()
 {
 #ifdef __LINUX__
     struct timeval tv;
-    gettimeofday(&tv, NULL);
-    SetSystemTimer(tv);
+    if (gettimeofday(&tv, NULL)<0)
+        Reset();
+    else
+        Set(tv);
 #else
     Reset();
@@ -98,4 +226,40 @@
 }
 
+// --------------------------------------------------------------------------
+//
+// Return contents as a TString of the form:
+//   "[yy]yy/mm/dd [h]h:mm:ss.fff"
+//
+TString MTime::GetString() const
+{
+    UShort_t y, ms;
+    Byte_t mon, d, h, m, s;
+
+    GetDate(y, mon, d);
+    GetTime(h, m, s, ms);
+
+    return TString(Form("%2d/%02d/%02d %d:%02d:%02d.%03d", y, mon, d, h, m, s, ms));
+}
+
+// --------------------------------------------------------------------------
+//
+// Return contents as a TString of the form:
+//   "yyyymmdd_hhmmss"
+//
+TString MTime::GetFileName() const
+{
+    UShort_t y;
+    Byte_t mon, d, h, m, s;
+
+    GetDate(y, mon, d);
+    GetTime(h, m, s);
+
+    return TString(Form("%04d%02d%02d_%02d%02d%02d", y, mon, d, h, m, s));
+}
+
+// --------------------------------------------------------------------------
+//
+// Print MTime as string
+//
 void MTime::Print(Option_t *) const
 {
@@ -107,5 +271,4 @@
 
     *fLog << GetDescriptor() << ": ";
-    *fLog << Form("%4d/%02d/%02d %02d:%02d:%02d.%03d (+%dns)",
-                  yea, mon, day, h, m, s, ms, fNanoSec) << endl;
+    *fLog << GetString() << Form(" (+%dns)", fNanoSec) << endl;
 } 
Index: /trunk/MagicSoft/Mars/mbase/MTime.h
===================================================================
--- /trunk/MagicSoft/Mars/mbase/MTime.h	(revision 2611)
+++ /trunk/MagicSoft/Mars/mbase/MTime.h	(revision 2612)
@@ -30,4 +30,7 @@
 
 private:
+    static const UInt_t kHour; // [ms] one hour
+    static const UInt_t kDay;  // [ms] one day
+
      UInt_t fMjd;     // [d]  Day in the century        (Day of sun rise)
      TTime  fTime;    // [ms] Time of Day               (-11h<=x<13h)
@@ -36,6 +39,10 @@
      ULong_t GetTime24() const
      {
-         const ULong_t hor = 3600000; // One Hour in milliseconds
-         return (Long_t)fTime<0 ? (Long_t)fTime+24*hor : (ULong_t)fTime;
+         return (Long_t)fTime<0 ? (Long_t)fTime+kDay : (ULong_t)fTime;
+     }
+     void Init(const char *name, const char *title)
+     {
+        fName  = name  ? name  : "MTime";
+        fTitle = title ? title : "Generalized time stamp";
      }
 
@@ -43,15 +50,18 @@
     MTime(const char *name=NULL, const char *title=NULL)
     {
-        fName = name ? name : ClassName();
-        fTitle = title;
-
+        Init(name, title);
         Reset();
     }
+    MTime(const struct timeval &tm)
+    {
+        Init(NULL, NULL);
+        Set(tm);
+    }
+    MTime(const MTime& t) : fMjd(t.fMjd), fTime(t.fTime), fNanoSec(t.fNanoSec)
+    {
+        Init(NULL, NULL);
+    }
 
-    MTime(MTime& t) { *this = t; }
-
-    void Reset() { fMjd=0; fTime=0; fNanoSec=0; }
-
-    void operator=(MTime &t)
+    void operator=(const MTime &t)
     {
         fMjd     = t.fMjd;
@@ -60,80 +70,43 @@
     }
 
+    void Reset() { fMjd=0; fTime=0; fNanoSec=0; }
+
     void Print(Option_t *t=NULL) const;
 
     void Now();
 
-    Double_t GetMjd() const
+    Bool_t   Set(UInt_t mjd, ULong_t ms, UInt_t ns=0);
+    Bool_t   Set(UShort_t y, Byte_t m, Byte_t d, Byte_t h, Byte_t min, Byte_t s, UShort_t ms, UInt_t ns=0);
+    void     Set(const struct timeval &tv);
+    void     SetCT1Time(UInt_t mjd, UInt_t t1, UInt_t t0);
+    void     SetMjd(Double_t m);
+    Double_t GetMjd() const;
+    TString  GetString() const;
+    TString  GetFileName() const;
+    void     GetDate(UShort_t &y, Byte_t &m, Byte_t &d) const;
+    TTime    GetRootTime() const;
+    Double_t GetAxisTime() const;
+    Long_t   GetTime() const { return (Long_t)fTime; } // [ms] Time of Day returned in the range [-11h, 13h)
+    void     GetTime(Byte_t &h, Byte_t &m, Byte_t &s, UShort_t &ms) const;
+    void     GetTime(Byte_t &h, Byte_t &m, Byte_t &s) const
     {
-        return fMjd+((Long_t)fTime+fNanoSec/1e6)/1000;
+        UShort_t ms;
+        GetTime(h, m, s, ms);
     }
 
-    void SetSystemTimer(const struct timeval &tv);
+    UInt_t Year() const  { UShort_t y; Byte_t m, d; GetDate(y,m,d); return y; }
+    UInt_t Month() const { UShort_t y; Byte_t m, d; GetDate(y,m,d); return m; }
+    UInt_t Day() const   { UShort_t y; Byte_t m, d; GetDate(y,m,d); return d; }
+    UInt_t Hour() const  { Byte_t h, m, s; GetTime(h,m,s); return h; }
+    UInt_t Min() const   { Byte_t h, m, s; GetTime(h,m,s); return m; }
+    UInt_t Sec() const   { Byte_t h, m, s; GetTime(h,m,s); return s; }
 
-    Bool_t Set(UInt_t mjd, ULong_t ms, UInt_t ns=0)
+    operator double() const   //[s]
     {
-        const ULong_t hor = 3600000; // One Hour in milliseconds
-        if (ms>24*hor-1 || ns>999999)
-            return kFALSE;
-
-        const Bool_t am = ms < hor*13;
-
-        fMjd     = am ? mjd : mjd + 1;
-        fTime    = (Long_t)(am ? ms  : ms - hor*24);
-        fNanoSec = ns%1000000;
-
-        return kTRUE;
-    }
-
-    Bool_t Set(UShort_t y, Byte_t m, Byte_t d, Byte_t h, Byte_t min, Byte_t s, UShort_t ms, UInt_t ns=0);
-
-    void SetCT1Time(UInt_t mjd, UInt_t t1, UInt_t t0)
-    {
-        // int   isecs_since_midday; // seconds passed since midday before sunset (JD of run start)
-        // int   isecfrac_200ns;     // fractional part of isecs_since_midday
-        // fTime->SetTime(isecfrac_200ns, isecs_since_midday);
-        const ULong_t hor = 3600000; // One Hour in milliseconds
-
-        fNanoSec         = (200*t1)%1000000;
-        const ULong_t ms = (200*t1)/1000000 + t0+12*hor;
-
-        fTime = (Long_t)(ms<13*hor ? ms : ms-24*hor);
-
-        fMjd = mjd+1;
-    }
-    /*
-    void SetSystemTime(const TTime &tm)
-    {
-        fTime = (ULong_t)tm%(24*hor);
-    }
-     */
-    operator double() const //[s]
-    {
-        return fMjd*24*3600+((Long_t)fTime+fNanoSec*1e6)*1000;
+        return ((Double_t)fMjd*kDay+(Long_t)fTime+fNanoSec/1e6)/1000;
     }
     double operator()() const //[s]
     {
         return operator double();
-    }
-
-    void GetDate(UShort_t &y, Byte_t &m, Byte_t &d) const;
-    void GetTime(Byte_t &h, Byte_t &m, Byte_t &s, UShort_t &ms) const // Time of Day returned in the range [0h, 24h)
-    {
-        Long_t tm = GetTime24();
-        ms  = tm%1000;
-        tm /= 1000;
-        s   = tm%60;
-        tm /= 60;
-        m   = tm%60;
-        tm /= 60;
-        h   = tm;
-    }
-    Long_t GetTime() const // Time of Day returned in the range [-11h, 13h)
-    { return (Long_t)fTime; }
-
-    void GetTime(Byte_t &h, Byte_t &m, Byte_t &s) const
-    {
-        UShort_t ms;
-        GetTime(h, m, s, ms);
     }
 
@@ -151,4 +124,5 @@
     return false;
 }
+
 inline bool operator>(MTime &t1, MTime &t2)
 {
@@ -161,19 +135,30 @@
     return false;
 }
+
 inline bool operator<=(MTime &t1, MTime &t2)
 {
     return !(t1>t2);
 }
+
 inline bool operator>=(MTime &t1, MTime &t2)
 {
     return !(t1<t2);
 }
+
 inline bool operator==(MTime &t1, MTime &t2)
 {
     return t1.fNanoSec==t2.fNanoSec && t1.fTime==t2.fTime && t1.fMjd==t2.fMjd;
 }
+
 inline bool operator!=(MTime &t1, MTime &t2)
 {
     return t1.fNanoSec!=t2.fNanoSec || t1.fTime!=t2.fTime || t1.fMjd!=t2.fMjd;
 }
+
+inline ostream &operator<<(ostream &out, MTime &t)
+{
+    out << t.GetString();
+    return out;
+}
+
 #endif
Index: /trunk/MagicSoft/Mars/mhist/MHPixVsTime.cc
===================================================================
--- /trunk/MagicSoft/Mars/mhist/MHPixVsTime.cc	(revision 2611)
+++ /trunk/MagicSoft/Mars/mhist/MHPixVsTime.cc	(revision 2612)
@@ -150,5 +150,5 @@
     Double_t t = 0;
     if (fUseEventTime)
-        t = fTime->GetTime();
+        t = fTime->GetAxisTime();
     else
         t = fHeader ? fHeader->GetDAQEvtNumber() : fGraph.GetN();
@@ -194,4 +194,9 @@
     gPad->SetBorderMode(0);
     fSum->Draw("EPhist");
+
+    fGraph->GetHistogram()->SetXTitle("Time");
+    fGraph->GetHistogram()->GetXaxis()->SetTimeFormat("%H:%M:%S %F1995-01-01 00:00:00");
+    fGraph->GetHistogram()->GetXaxis()->SetTimeDisplay(1);
+    fGraph->GetHistogram()->GetXaxis()->SetLabelSize(0.033);
     */
 }
Index: /trunk/MagicSoft/Mars/mhist/MHVsTime.cc
===================================================================
--- /trunk/MagicSoft/Mars/mhist/MHVsTime.cc	(revision 2611)
+++ /trunk/MagicSoft/Mars/mhist/MHVsTime.cc	(revision 2612)
@@ -165,5 +165,5 @@
             return kFALSE;
         }
-        t = tm->GetTime();
+        t = tm->GetAxisTime();
     }
 
@@ -207,5 +207,5 @@
     {
         fGraph->GetHistogram()->SetXTitle("Time");
-        fGraph->GetHistogram()->GetXaxis()->SetTimeFormat("%H:%M:%S");
+        fGraph->GetHistogram()->GetXaxis()->SetTimeFormat("%H:%M:%S %F1995-01-01 00:00:00");
         fGraph->GetHistogram()->GetXaxis()->SetTimeDisplay(1);
         fGraph->GetHistogram()->GetXaxis()->SetLabelSize(0.033);
