ROOT logo
// $Id: GTime.cxx 2800 2012-06-29 06:34:53Z matevz $

// Copyright (C) 1999-2008, Matevz Tadel. All rights reserved.
// This file is part of GLED, released under GNU General Public License version 2.
// For the licensing terms see $GLEDSYS/LICENSE or http://www.gnu.org/.

#include "GTime.h"
#include <climits>
#include <ctime>
#include <sys/time.h>

//______________________________________________________________________
//

#define NANO_FAK 1000000000

ClassImp(GTime);

GTime GTime::sApproximateTime(GTime::I_Now);

GTime::GTime(Init_e i)
{
  switch (i)
  {
    case I_Zero:  SetZero();  break;
    case I_Now:   SetNow();   break;
    case I_Never: SetNever(); break;
  }
}

void GTime::canonize()
{
  if (mNSec < 0) {
    Long64_t uf = 1 - mNSec / NANO_FAK;
    mSec  -= uf;
    mNSec += NANO_FAK * uf;
  }
  else if (mNSec > NANO_FAK) {
    Long64_t of = mNSec / NANO_FAK;
    mSec  += of;
    mNSec -= NANO_FAK * of;
  }
}

//==============================================================================

void GTime::SetNow()
{
  struct timeval t;
  gettimeofday(&t, 0);
  mSec  = t.tv_sec;
  mNSec = t.tv_usec * 1000;
}

GTime GTime::TimeUntilNow()
{
  GTime n(I_Now);
  n -= *this;
  return n;
}

void GTime::SetNever()
{
  mSec = mNSec = LLONG_MIN;
}

Bool_t GTime::IsNever() const
{
  return mSec == LLONG_MIN && mNSec == LLONG_MIN;
}

//==============================================================================

GTime& GTime::operator=(Double_t sec)
{
  mSec = (Long64_t) sec;
  if (sec < 0) --mSec;
  mNSec = (Long64_t) (NANO_FAK * (sec - mSec));
  return *this;
}

//==============================================================================

GTime& GTime::operator+=(const GTime& t)
{
  mSec   += t.mSec;
  mNSec += t.mNSec;
  if (mNSec > NANO_FAK) {
    ++mSec;
    mNSec -= NANO_FAK;
  }
  return *this;
}

GTime& GTime::operator-=(const GTime& t)
{
  mSec  -= t.mSec;
  mNSec -= t.mNSec;
  if (mNSec < 0) {
    --mSec;
    mNSec += NANO_FAK;
  }
  return *this;
}

GTime& GTime::operator+=(Double_t sec)
{
  GTime tt(sec);
  *this += tt;
  return *this;
}

GTime& GTime::operator-=(Double_t sec)
{
  GTime tt(sec);
  *this -= tt;
  return *this;
}

/**************************************************************************/

GTime GTime::operator+(const GTime& t) const
{
  GTime r(*this);
  r += t;
  return r;
}

GTime GTime::operator-(const GTime& t) const
{
  GTime r(*this);
  r -= t;
  return r;
}

/**************************************************************************/

bool GTime::operator<(const GTime& t) const
{
  if(mSec == t.mSec) return mNSec < t.mNSec;
  return mSec < t.mSec;
}

bool GTime::operator>(const GTime& t) const
{
  if(mSec == t.mSec) return mNSec > t.mNSec;
  return mSec > t.mSec;
}

bool GTime::operator<=(const GTime& t) const
{
  if(mSec == t.mSec) return mNSec <= t.mNSec;
  return mSec <= t.mSec;
}

bool GTime::operator>=(const GTime& t) const
{
  if(mSec == t.mSec) return mNSec >= t.mNSec;
  return mSec >= t.mSec;
}

bool GTime::operator==(const GTime& t) const
{
  return mNSec == t.mNSec && mSec == t.mSec;
}

//==============================================================================

namespace
{
  typedef struct tm* (time_foo_r)(const time_t*, struct tm*);

  TString to_asctime(Long64_t sec, time_foo_r foo, Bool_t show_tz)
  {
    time_t    time(sec);
    struct tm t;
    char      buf[32];
    TString   txt(asctime_r(foo(&time, &t), buf));
    txt.Chop();
    if (show_tz) {
      txt += " ";
      txt += (foo == gmtime_r) ? "UTC" : t.tm_zone;
    }
    return txt;
  }

  TString to_datetime(Long64_t sec, time_foo_r foo, Bool_t show_tz)
  {
    time_t    time(sec);
    struct tm t;
    foo(&time, &t);
    TString txt;
    txt.Form("%d-%02d-%02d %02d:%02d:%02d", 1900 + t.tm_year, 1 + t.tm_mon, t.tm_mday, t.tm_hour, t.tm_min, t.tm_sec);
    if (show_tz) {
      txt += " ";
      txt += (foo == gmtime_r) ? "UTC" : t.tm_zone;
    }
    return txt;
  }

  TString to_date(Long64_t sec, time_foo_r foo)
  {
    time_t    time(sec);
    struct tm t;
    foo(&time, &t);
    TString txt;
    txt.Form("%d-%02d-%02d", 1900 + t.tm_year, 1 + t.tm_mon, t.tm_mday);
    return txt;
  }

  TString to_compact_datetime(Long64_t sec, time_foo_r foo)
  {
    time_t    time(sec);
    struct tm t;
    foo(&time, &t);
    return TString::Format("%d%02d%02d-%02d%02d%02d", 1900 + t.tm_year, 1 + t.tm_mon, t.tm_mday, t.tm_hour, t.tm_min, t.tm_sec);
  }

  TString to_webtime(Long64_t sec, time_foo_r foo, Bool_t show_tz)
  {
    static const char *day_names[] = { "Sun", "Mon", "Tue", "Wed",  "Thu",  "Fri", "Sat" };
    static const char *month_names[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun",
                                         "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };

    time_t    time(sec);
    struct tm t;
    foo(&time, &t);
    TString txt;
    txt.Form("%s, %d %s %d %02d:%02d:%02d", day_names[t.tm_wday], t.tm_mday,
	     month_names[t.tm_mon], 1900 + t.tm_year, t.tm_hour, t.tm_min, t.tm_sec);
    if (show_tz) {
      txt += " ";
      txt += (foo == gmtime_r) ? "GMT" : t.tm_zone;
    }
    return txt;
  }
}

TString GTime::ToAscUTC(Bool_t show_tz) const
{
  return IsNever() ? "Never" : to_asctime(mSec, gmtime_r, show_tz);
}

TString GTime::ToAscLocal(Bool_t show_tz) const
{
  return IsNever() ? "Never" : to_asctime(mSec, localtime_r, show_tz);
}

TString GTime::ToDateTimeUTC(Bool_t show_tz) const
{
  return IsNever() ? "Never" : to_datetime(mSec, gmtime_r, show_tz);
}

TString GTime::ToDateTimeLocal(Bool_t show_tz) const
{
  return IsNever() ? "Never" : to_datetime(mSec, localtime_r, show_tz);
}

TString GTime::ToCompactDateTimeUTC() const
{
  return IsNever() ? "Never" : to_compact_datetime(mSec, gmtime_r);
}

TString GTime::ToCompactDateTimeLocal() const
{
  return IsNever() ? "Never" : to_compact_datetime(mSec, localtime_r);
}

TString GTime::ToDateUTC() const
{
  return IsNever() ? "Never" : to_date(mSec, gmtime_r);
}

TString GTime::ToDateLocal() const
{
  return IsNever() ? "Never" : to_date(mSec, localtime_r);
}

TString GTime::ToWebTimeGMT(Bool_t show_tz) const
{
  return IsNever() ? "Never" : to_webtime(mSec, gmtime_r, show_tz);
}

TString GTime::ToWebTimeLocal(Bool_t show_tz) const
{
  return IsNever() ? "Never" : to_webtime(mSec, localtime_r, show_tz);
}

TString GTime::ToHourMinSec(Bool_t force_non_negative) const
{
  // Format as hh:mm:ss, useful for time differences.

  if (IsNever()) return "Never";

  Long64_t osec  = mSec;
  if (force_non_negative && osec < 0) osec = 0;

  Long64_t hours = osec / 3600;
  Int_t    sah   = osec % 3600;
  Int_t    min   = sah / 60;
  Int_t    sec   = sah % 60;
  return TString::Format("%02lld:%02d:%02d", hours, min, sec);    
}

//------------------------------------------------------------------------------

GTime GTime::TimeOfTheDayUTC() const
{
  time_t    time(mSec);
  struct tm t;
  gmtime_r(&time, &t);
  return GTime(3600*t.tm_hour + 60*t.tm_min + t.tm_sec, 0);
}

GTime GTime::TimeOfTheDayLocal() const
{
  time_t    time(mSec);
  struct tm t;
  localtime_r(&time, &t);
  return GTime(3600*t.tm_hour + 60*t.tm_min + t.tm_sec, 0);
 
}

//==============================================================================

void GTime::Sleep()
{
  struct timespec req, rem;
  req.tv_sec  = mSec;
  req.tv_nsec = mNSec;
  if (nanosleep(&req, &rem))
    perror("GTime::Sleep");
  // !!! Should sleep on? Need flag.
}

//------------------------------------------------------------------------------

Long64_t GTime::SleepMiliSec(UInt_t ms,
			     Bool_t break_on_signal,
			     Bool_t warn_on_signal)
{
  struct timespec req, rem;
  req.tv_sec  = ms / 1000;
  req.tv_nsec = (ms % 1000) * 1000000;

  while (true)
  {
    if (nanosleep(&req, &rem))
    {
      if (warn_on_signal)
      {
	perror("GTime::SleepMiliSec");
      }
      if (break_on_signal)
      {
	Long64_t remms = 1000ll*rem.tv_sec + rem.tv_nsec / 1000000;
	return remms;
      }
      else
      {
	req = rem;
      }
    }
    else
    {
      return 0;
    }
  }
}

//==============================================================================

const GTime& GTime::ApproximateTime()
{
  // Returns approximate time, rounded to one second.

  return sApproximateTime;
}

Long64_t GTime::UpdateApproximateTime(const GTime& now)
{
  if (now.mNSec > 500000000)
    sApproximateTime.mSec = now.mSec + 1;
  else
    sApproximateTime.mSec = now.mSec;

  return sApproximateTime.mSec;
}

//==============================================================================

void GTime::NetStreamer(TBuffer& b)
{
  if (b.IsReading())
  {
    b >> mSec >> mNSec;
  }
  else
  {
    b << mSec << mNSec;
  }
}
 GTime.cxx:1
 GTime.cxx:2
 GTime.cxx:3
 GTime.cxx:4
 GTime.cxx:5
 GTime.cxx:6
 GTime.cxx:7
 GTime.cxx:8
 GTime.cxx:9
 GTime.cxx:10
 GTime.cxx:11
 GTime.cxx:12
 GTime.cxx:13
 GTime.cxx:14
 GTime.cxx:15
 GTime.cxx:16
 GTime.cxx:17
 GTime.cxx:18
 GTime.cxx:19
 GTime.cxx:20
 GTime.cxx:21
 GTime.cxx:22
 GTime.cxx:23
 GTime.cxx:24
 GTime.cxx:25
 GTime.cxx:26
 GTime.cxx:27
 GTime.cxx:28
 GTime.cxx:29
 GTime.cxx:30
 GTime.cxx:31
 GTime.cxx:32
 GTime.cxx:33
 GTime.cxx:34
 GTime.cxx:35
 GTime.cxx:36
 GTime.cxx:37
 GTime.cxx:38
 GTime.cxx:39
 GTime.cxx:40
 GTime.cxx:41
 GTime.cxx:42
 GTime.cxx:43
 GTime.cxx:44
 GTime.cxx:45
 GTime.cxx:46
 GTime.cxx:47
 GTime.cxx:48
 GTime.cxx:49
 GTime.cxx:50
 GTime.cxx:51
 GTime.cxx:52
 GTime.cxx:53
 GTime.cxx:54
 GTime.cxx:55
 GTime.cxx:56
 GTime.cxx:57
 GTime.cxx:58
 GTime.cxx:59
 GTime.cxx:60
 GTime.cxx:61
 GTime.cxx:62
 GTime.cxx:63
 GTime.cxx:64
 GTime.cxx:65
 GTime.cxx:66
 GTime.cxx:67
 GTime.cxx:68
 GTime.cxx:69
 GTime.cxx:70
 GTime.cxx:71
 GTime.cxx:72
 GTime.cxx:73
 GTime.cxx:74
 GTime.cxx:75
 GTime.cxx:76
 GTime.cxx:77
 GTime.cxx:78
 GTime.cxx:79
 GTime.cxx:80
 GTime.cxx:81
 GTime.cxx:82
 GTime.cxx:83
 GTime.cxx:84
 GTime.cxx:85
 GTime.cxx:86
 GTime.cxx:87
 GTime.cxx:88
 GTime.cxx:89
 GTime.cxx:90
 GTime.cxx:91
 GTime.cxx:92
 GTime.cxx:93
 GTime.cxx:94
 GTime.cxx:95
 GTime.cxx:96
 GTime.cxx:97
 GTime.cxx:98
 GTime.cxx:99
 GTime.cxx:100
 GTime.cxx:101
 GTime.cxx:102
 GTime.cxx:103
 GTime.cxx:104
 GTime.cxx:105
 GTime.cxx:106
 GTime.cxx:107
 GTime.cxx:108
 GTime.cxx:109
 GTime.cxx:110
 GTime.cxx:111
 GTime.cxx:112
 GTime.cxx:113
 GTime.cxx:114
 GTime.cxx:115
 GTime.cxx:116
 GTime.cxx:117
 GTime.cxx:118
 GTime.cxx:119
 GTime.cxx:120
 GTime.cxx:121
 GTime.cxx:122
 GTime.cxx:123
 GTime.cxx:124
 GTime.cxx:125
 GTime.cxx:126
 GTime.cxx:127
 GTime.cxx:128
 GTime.cxx:129
 GTime.cxx:130
 GTime.cxx:131
 GTime.cxx:132
 GTime.cxx:133
 GTime.cxx:134
 GTime.cxx:135
 GTime.cxx:136
 GTime.cxx:137
 GTime.cxx:138
 GTime.cxx:139
 GTime.cxx:140
 GTime.cxx:141
 GTime.cxx:142
 GTime.cxx:143
 GTime.cxx:144
 GTime.cxx:145
 GTime.cxx:146
 GTime.cxx:147
 GTime.cxx:148
 GTime.cxx:149
 GTime.cxx:150
 GTime.cxx:151
 GTime.cxx:152
 GTime.cxx:153
 GTime.cxx:154
 GTime.cxx:155
 GTime.cxx:156
 GTime.cxx:157
 GTime.cxx:158
 GTime.cxx:159
 GTime.cxx:160
 GTime.cxx:161
 GTime.cxx:162
 GTime.cxx:163
 GTime.cxx:164
 GTime.cxx:165
 GTime.cxx:166
 GTime.cxx:167
 GTime.cxx:168
 GTime.cxx:169
 GTime.cxx:170
 GTime.cxx:171
 GTime.cxx:172
 GTime.cxx:173
 GTime.cxx:174
 GTime.cxx:175
 GTime.cxx:176
 GTime.cxx:177
 GTime.cxx:178
 GTime.cxx:179
 GTime.cxx:180
 GTime.cxx:181
 GTime.cxx:182
 GTime.cxx:183
 GTime.cxx:184
 GTime.cxx:185
 GTime.cxx:186
 GTime.cxx:187
 GTime.cxx:188
 GTime.cxx:189
 GTime.cxx:190
 GTime.cxx:191
 GTime.cxx:192
 GTime.cxx:193
 GTime.cxx:194
 GTime.cxx:195
 GTime.cxx:196
 GTime.cxx:197
 GTime.cxx:198
 GTime.cxx:199
 GTime.cxx:200
 GTime.cxx:201
 GTime.cxx:202
 GTime.cxx:203
 GTime.cxx:204
 GTime.cxx:205
 GTime.cxx:206
 GTime.cxx:207
 GTime.cxx:208
 GTime.cxx:209
 GTime.cxx:210
 GTime.cxx:211
 GTime.cxx:212
 GTime.cxx:213
 GTime.cxx:214
 GTime.cxx:215
 GTime.cxx:216
 GTime.cxx:217
 GTime.cxx:218
 GTime.cxx:219
 GTime.cxx:220
 GTime.cxx:221
 GTime.cxx:222
 GTime.cxx:223
 GTime.cxx:224
 GTime.cxx:225
 GTime.cxx:226
 GTime.cxx:227
 GTime.cxx:228
 GTime.cxx:229
 GTime.cxx:230
 GTime.cxx:231
 GTime.cxx:232
 GTime.cxx:233
 GTime.cxx:234
 GTime.cxx:235
 GTime.cxx:236
 GTime.cxx:237
 GTime.cxx:238
 GTime.cxx:239
 GTime.cxx:240
 GTime.cxx:241
 GTime.cxx:242
 GTime.cxx:243
 GTime.cxx:244
 GTime.cxx:245
 GTime.cxx:246
 GTime.cxx:247
 GTime.cxx:248
 GTime.cxx:249
 GTime.cxx:250
 GTime.cxx:251
 GTime.cxx:252
 GTime.cxx:253
 GTime.cxx:254
 GTime.cxx:255
 GTime.cxx:256
 GTime.cxx:257
 GTime.cxx:258
 GTime.cxx:259
 GTime.cxx:260
 GTime.cxx:261
 GTime.cxx:262
 GTime.cxx:263
 GTime.cxx:264
 GTime.cxx:265
 GTime.cxx:266
 GTime.cxx:267
 GTime.cxx:268
 GTime.cxx:269
 GTime.cxx:270
 GTime.cxx:271
 GTime.cxx:272
 GTime.cxx:273
 GTime.cxx:274
 GTime.cxx:275
 GTime.cxx:276
 GTime.cxx:277
 GTime.cxx:278
 GTime.cxx:279
 GTime.cxx:280
 GTime.cxx:281
 GTime.cxx:282
 GTime.cxx:283
 GTime.cxx:284
 GTime.cxx:285
 GTime.cxx:286
 GTime.cxx:287
 GTime.cxx:288
 GTime.cxx:289
 GTime.cxx:290
 GTime.cxx:291
 GTime.cxx:292
 GTime.cxx:293
 GTime.cxx:294
 GTime.cxx:295
 GTime.cxx:296
 GTime.cxx:297
 GTime.cxx:298
 GTime.cxx:299
 GTime.cxx:300
 GTime.cxx:301
 GTime.cxx:302
 GTime.cxx:303
 GTime.cxx:304
 GTime.cxx:305
 GTime.cxx:306
 GTime.cxx:307
 GTime.cxx:308
 GTime.cxx:309
 GTime.cxx:310
 GTime.cxx:311
 GTime.cxx:312
 GTime.cxx:313
 GTime.cxx:314
 GTime.cxx:315
 GTime.cxx:316
 GTime.cxx:317
 GTime.cxx:318
 GTime.cxx:319
 GTime.cxx:320
 GTime.cxx:321
 GTime.cxx:322
 GTime.cxx:323
 GTime.cxx:324
 GTime.cxx:325
 GTime.cxx:326
 GTime.cxx:327
 GTime.cxx:328
 GTime.cxx:329
 GTime.cxx:330
 GTime.cxx:331
 GTime.cxx:332
 GTime.cxx:333
 GTime.cxx:334
 GTime.cxx:335
 GTime.cxx:336
 GTime.cxx:337
 GTime.cxx:338
 GTime.cxx:339
 GTime.cxx:340
 GTime.cxx:341
 GTime.cxx:342
 GTime.cxx:343
 GTime.cxx:344
 GTime.cxx:345
 GTime.cxx:346
 GTime.cxx:347
 GTime.cxx:348
 GTime.cxx:349
 GTime.cxx:350
 GTime.cxx:351
 GTime.cxx:352
 GTime.cxx:353
 GTime.cxx:354
 GTime.cxx:355
 GTime.cxx:356
 GTime.cxx:357
 GTime.cxx:358
 GTime.cxx:359
 GTime.cxx:360
 GTime.cxx:361
 GTime.cxx:362
 GTime.cxx:363
 GTime.cxx:364
 GTime.cxx:365
 GTime.cxx:366
 GTime.cxx:367
 GTime.cxx:368
 GTime.cxx:369
 GTime.cxx:370
 GTime.cxx:371
 GTime.cxx:372
 GTime.cxx:373
 GTime.cxx:374
 GTime.cxx:375
 GTime.cxx:376
 GTime.cxx:377
 GTime.cxx:378
 GTime.cxx:379
 GTime.cxx:380
 GTime.cxx:381
 GTime.cxx:382
 GTime.cxx:383
 GTime.cxx:384
 GTime.cxx:385
 GTime.cxx:386
 GTime.cxx:387
 GTime.cxx:388
 GTime.cxx:389
 GTime.cxx:390
 GTime.cxx:391
 GTime.cxx:392
 GTime.cxx:393
 GTime.cxx:394
 GTime.cxx:395
 GTime.cxx:396
 GTime.cxx:397
 GTime.cxx:398
 GTime.cxx:399
 GTime.cxx:400
 GTime.cxx:401
 GTime.cxx:402