/* ======================================================================== *\ ! ! * ! * This file is part of MARS, the MAGIC Analysis and Reconstruction ! * Software. It is distributed to you in the hope that it can be a useful ! * and timesaving tool in analysing Data of imaging Cerenkov telescopes. ! * It is distributed WITHOUT ANY WARRANTY. ! * ! * Permission to use, copy, modify and distribute this software and its ! * documentation for any purpose is hereby granted without fee, ! * provided that the above copyright notice appear in all copies and ! * that both that copyright notice and this permission notice appear ! * in supporting documentation. It is provided "as is" without express ! * or implied warranty. ! * ! ! ! Author(s): Thomas Bretz 12/2000 ! ! Copyright: MAGIC Software Development, 2000-2003 ! ! \* ======================================================================== */ ///////////////////////////////////////////////////////////////////////////// // // MTime // // A generalized MARS time stamp. // // WARNING: Be carefull changing this class. It is also used in the // MAGIC drive software cosy! // // Remarke: If you encounter strange behaviour, check the casting. // Note, that on Linux machines ULong_t and UInt_t is the same. // // Version 1: // ---------- // - first version // // Version 2: // ---------- // - removed fTimeStamp[2] // // Version 3: // ---------- // - removed fDurtaion - we may put it back when it is needed // - complete rewrite of the data members (old ones completely replaced) // ///////////////////////////////////////////////////////////////////////////// #include "MTime.h" #include #include // struct timeval #include #include "MLog.h" #include "MAstro.h" ClassImp(MTime); 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 { MAstro::Mjd2Ymd((Long_t)fTime<0?fMjd-1:fMjd, y, m, d); } // -------------------------------------------------------------------------- // // 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) { // [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) { if (h>23 || min>59 || s>59 || ms>999 || ns>999999) return kFALSE; const Int_t mjd = MAstro::Ymd2Mjd(y, m, d); if (mjd<0) return kFALSE; const ULong_t tm = ((((h*60+min)*60)+s)*1000)+ms; return Set(mjd, tm, ns); } // -------------------------------------------------------------------------- // // 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; } // -------------------------------------------------------------------------- // // Update the magic time. Make sure, that the MJD is set correctly. // It must be the MJD of the corresponding night. You can set it // by Set(2003, 12, 24); // // It is highly important, that the time correspoding to the night is // between 13:00:00.0 (day of dawning) and 12:59:59.999 (day of sunrise) // Bool_t MTime::UpdMagicTime(Byte_t h, Byte_t m, Byte_t s, UShort_t ms) { if (h>23 || m>59 || s>59 || ms>999) return kFALSE; const ULong_t tm = ((((h*60+m)*60)+s)*1000)+ms; fTime = (Long_t)(tm < kHour*13 ? tm : tm-kDay); // day of sunrise? //fNanoSec = ns; return kTRUE; } // -------------------------------------------------------------------------- // // 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; if (gettimeofday(&tv, NULL)<0) Reset(); else Set(tv); #else Reset(); #endif } // -------------------------------------------------------------------------- // // Return contents as a TString of the form: // "yyyy/mm/dd hh: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("%4d/%02d/%02d %02d:%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 { UShort_t yea, ms; Byte_t mon, day, h, m, s; GetDate(yea, mon, day); GetTime(h, m, s, ms); *fLog << GetDescriptor() << ": "; *fLog << GetString() << Form(" (+%dns)", fNanoSec) << endl; } istream &MTime::ReadBinary(istream &fin) { UShort_t y; Byte_t mon, d, h, m, s; fin.read((char*)&y, 2); fin.read((char*)&mon, 1); fin.read((char*)&d, 1); fin.read((char*)&h, 1); fin.read((char*)&m, 1); fin.read((char*)&s, 1); // Total=7 Set(y, mon, d, h, m, s, 0); return fin; }