LCIO  02.17
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
LCTime.cc
Go to the documentation of this file.
1 #include "UTIL/LCTime.h"
2 #include "Exceptions.h"
3 #include <time.h>
4 
5 #include <sstream>
6 #include <iomanip>
7 #include <cstdlib>
8 
9 // the canonical year zero
10 #define YEAR0 1970
11 
12 // seconds per min, hour, day
13 #define SPM 60
14 #define SPH 3600 // 60*60
15 #define SPD 86400 // 60*60*24
16 
17 #define DPY 365 // days per year - no leap year
18 #define NPS 1000000000LL // ns per s - need 64bit to force result of conversion to be 64bit
19 
20 using namespace EVENT ;
21 
22 #include <iostream>
23 using namespace std ;
24 
25 namespace UTIL{
26 
27  const int LCTime::dpm[13] = { 0,31,28,31,30,31,30,31,31,30,31,30,31 } ;
28 
29 
30  LCTime::LCTime(){
31 
32  time_t now ;
33  time ( &now ) ;
34 
35  _t = now * NPS ;
36 
37  convertToCalTime() ;
38 
39 
40 // // selftest :
41 // cout << "--- date : " << getDateString()
42 // << endl
43 // << "--- time: " << _t << endl
44 // << endl ;
45 
46 // convertFromCalTime() ;
47 // convertToCalTime() ;
48 
49 // cout << "after reconversion " << endl ;
50 // // selftest :
51 // cout << "--- date : " << getDateString()
52 // << endl
53 // << "--- time: " << _t << endl
54 // << endl ;
55 
56  }
57 
58  LCTime::LCTime( long64 time) : _t( time ) {
59 
61  }
62 
63 
64  LCTime::LCTime(int y, int mon, int d, int h, int m, int s ){
65 
66 
67  _d.year = y ;
68  _d.month = mon ;
69  _d.day = d ;
70  _d.hour = h ;
71  _d.min = m ;
72  _d.sec = s ;
73  _d.ns = 0 ;
74 
75  // do some sanity checks on date:
76  if( y < YEAR0 ||
77  mon < 0 || mon > 12 ||
78  d < 0 || d > daysInMonth( mon , y ) ){
79 
80  throw Exception( "LCTime::LCTime() invalid date:"+ getDateString() ) ;
81  }
82 
83 
85  }
86 
87  LCTime::LCTime( int unix_time) {
88 
89  _t = unix_time * NPS ;
90 
92  }
93 
94 
95 
97 
98  // initialize date to 1.1.1970
99  _d.year = YEAR0 ;
100  _d.month = 1 ;
101  _d.day = 1 ;
102  _d.hour = 0 ;
103  _d.min = 0 ;
104  _d.sec = 0 ;
105  _d.ns = 0 ;
106 
107  // don't support negative times
108  if( _t < 0LL ) {
109  _t = 0 ;
110  return ; // map to 1.1.1970 00:00:00
111  }
112 
113  // start with unix time, i.e. seconds since 1.1.1970
114  long64 s = _t / NPS ;
115  _d.ns = _t % NPS ;
116 
117  // total number of days
118  int nDays = s / SPD ;
119 
120  int daysLeft ;
121 
122  while( (daysLeft = nDays - daysInYear( _d.year ) ) >= 0 ){
123  nDays = daysLeft ;
124  _d.year ++ ;
125  }
126 
127 // std::cout << " ---- daysLeft : " << daysLeft << " year: " << _d.year << std::endl ;
128 
129  while( (daysLeft = nDays - daysInMonth( _d.month , _d.year ) ) >= 0 ){
130  nDays = daysLeft ;
131  _d.month ++ ;
132  }
133 
134 // std::cout << " ---- daysLeft : " << daysLeft << " month: " << _d.month << std::endl ;
135 
136  _d.day += nDays ;
137 
138 // std::cout << " ---- daysLeft : " << _d.day << std::endl ;
139 
140 
141 // if( _d.day > daysInMonth( _d.month , _d.year ) ) { // happens on first day of a month
142 // if( _d.month == 12 ) {
143 // _d.year += 1 ;
144 // _d.month = 1 ;
145 // } else {
146 // _d.month += 1 ;
147 // }
148 // _d.day = 1 ;
149 // }
150 
151 
152 
153  s = s % SPD ; // the seconds of the current day
154 
155  _d.hour = s / SPH ; // the hours of the current day
156 
157  s = s % SPH ; // the seconds of the current hour
158 
159  _d.min = s / SPM ; // the min of the current hour
160 
161  _d.sec = s % SPM ; // secs
162 
163  }
164 
166 
167  // don't support dates before 1.1.1970 00:00:00
168  if( _d.year < YEAR0 ) { // map to 1.1.1970 00:00:00
169  _t = -1 ;
170  convertToCalTime() ;
171  }
172 
173 
174  // add up all days that have passed
175  unsigned nDays = 0 ;
176 
177  for( int y = YEAR0 ; y < _d.year ; y ++ ){
178  nDays += daysInYear( y ) ;
179  }
180 
181  for( int m = 1 ; m < _d.month ; m ++ ){
182  nDays += daysInMonth( m , _d.year ) ;
183  }
184 
185  nDays += _d.day - 1 ; // current day hasn't passed yet
186 
187  // add up the seconds
188  _t = nDays * SPD + _d.hour * SPH + _d.min * SPM + _d.sec ;
189 
190  // now make ns
191  _t *= NPS ;
192 
193  }
194 
195 
196  int LCTime::daysInYear( int y ) const {
197  int d = DPY ;
198  if( isLeapYear( y ) ) ++d ;
199  return d ;
200  }
201 
202  int LCTime::daysInMonth( int mon , int y ) const {
203 
204  if( mon < 1 || mon > 12 )
205  return 0 ;
206  int d = dpm[ mon ] ;
207 
208  if( mon == 2 && isLeapYear( y ) ) d++ ;
209  return d ;
210  }
211 
212 
214  _t += t ;
215  convertToCalTime() ;
216  }
217 
218 
219 
221 
222  std::stringstream out ;
223 
224  // dd.mm.yyyy hh:mm:ss._ms_us_ns
225  out << setfill ('0')
226  << std::setw(2) << (int) _d.day
227  << std::setw(1) << "."
228  << std::setw(2) << (int) _d.month
229  << std::setw(1) << "."
230  << std::setw(4) << _d.year
231  << std::setw(1) << " "
232  << std::setw(2) << (int) _d.hour
233  << std::setw(1) << ":"
234  << std::setw(2) << (int) _d.min
235  << std::setw(1) << ":"
236  << std::setw(2) << (int) _d.sec
237  << std::setw(1) << "."
238  << std::setw(9) << (int) _d.ns ;
239 
240  return out.str() ;
241  }
242 
243 
244  bool LCTime::test( int nDates ) {
245 
246  std::cout << "LCTime::test: test LCTime with " << nDates << " random dates " << std::endl ;
247 
248  LCTime lcTime ;
249 
250  for(int i=0; i<nDates;i++){
251 
252  CalendarTime date ;
253  date.year = int( YEAR0 + 75 * ( 1.*std::rand()/RAND_MAX ) ) ;
254  date.month = int( 1 + 12 * ( 1.*std::rand()/RAND_MAX ) ) ;
255 
256  date.day = int( 1 + lcTime.daysInMonth( date.month, date.year) * ( 1.*std::rand()/RAND_MAX ) ) ;
257  date.hour = int( 0 + 24 * ( 1.*std::rand()/RAND_MAX ) ) ;
258  date.min = int( 0 + 60 * ( 1.*std::rand()/RAND_MAX ) ) ;
259  date.sec = int( 0 + 60 * ( 1.*std::rand()/RAND_MAX ) ) ;
260  date.ns =int( 0 ) ;
261 
262 
263 
264  LCTime testTime0( (int) date.year, (int) date.month, (int) date.day,
265  (int) date.hour, (int) date.min, (int) date.sec ) ;
266 
267  LCTime testTime1( testTime0.timeStamp() ) ;
268 
269 
270 // if( date.day == lcTime.daysInMonth( date.month, date.year) ) {
271 // std::cout << " last day in month : " << testTime0.getDateString() << std::endl ;
272 // }
273 
274 // std::cout << " random date: "
275 // << setfill ('0')
276 // << std::setw(2) << (int) date.day
277 // << std::setw(1) << "."
278 // << std::setw(2) << (int) date.month
279 // << std::setw(1) << "."
280 // << std::setw(4) << date.year
281 // << std::setw(1) << " "
282 // << std::setw(2) << (int) date.hour
283 // << std::setw(1) << ":"
284 // << std::setw(2) << (int) date.min
285 // << std::setw(1) << ":"
286 // << std::setw(2) << (int) date.sec
287 // << std::setw(1) << "."
288 // << std::setw(9) << (int) date.ns
289 // << std::endl ;
290 
291 // std::cout << " time0 : " << testTime0.getDateString() << std::endl ;
292 // std::cout << " time1 : " << testTime1.getDateString() << std::endl ;
293 // std::cout << "--------------------------------------------------------" << std::endl ;
294 
295 
296  if( testTime0.getDateString() != testTime1.getDateString() ){
297 
298  std::cout << " Erorr: incompatible date strings found: " << std::endl ;
299 
300  std::cout << " time0 : " << testTime0.getDateString() << std::endl ;
301  std::cout << " time1 : " << testTime1.getDateString() << std::endl ;
302 
303  }
304  if( date.year != testTime0.year() ||
305  date.month != testTime0.month() ||
306  date.day != testTime0.day() ||
307  date.hour != testTime0.hour() ||
308  date.min != testTime0.min() ||
309  date.sec != testTime0.sec() ||
310  date.ns != testTime0.ns () ) {
311 
312  std::cout << " Erorr: wrong date in LCTime: " << std::endl ;
313  std::cout << " random date: "
314  << setfill ('0')
315  << std::setw(2) << (int) date.day
316  << std::setw(1) << "."
317  << std::setw(2) << (int) date.month
318  << std::setw(1) << "."
319  << std::setw(4) << date.year
320  << std::setw(1) << " "
321  << std::setw(2) << (int) date.hour
322  << std::setw(1) << ":"
323  << std::setw(2) << (int) date.min
324  << std::setw(1) << ":"
325  << std::setw(2) << (int) date.sec
326  << std::setw(1) << "."
327  << std::setw(9) << (int) date.ns
328  << std::endl ;
329 
330  std::cout << " time0 : " << testTime0.getDateString() << std::endl ;
331 
332  }
333 
334  }
335 
336  return true ;
337  }
338 
339 }
Base exception class for LCIO - all other exceptions extend this.
Definition: Exceptions.h:21
int year() const
Calendar time: year.
Definition: LCTime.h:84
int sec() const
Calendar time: sec.
Definition: LCTime.h:99
T rand(T...args)
T endl(T...args)
void convertToCalTime()
Definition: LCTime.cc:96
#define NPS
Definition: LCTime.cc:18
int daysInMonth(int m, int y) const
The number if days in the given month and year in the Gregorian calendar.
Definition: LCTime.cc:202
T time(T...args)
T setw(T...args)
long long long64
64 bit signed integer,e.g.to be used for timestamps
Definition: LCIOTypes.h:14
STL class.
Helper class that allows to convert time stamps as defined in LCEvent::getTimeStamp() ( ns since 1...
Definition: LCTime.h:19
EVENT::long64 _t
Definition: LCTime.h:119
#define SPM
Definition: LCTime.cc:13
#define SPD
Definition: LCTime.cc:15
int month() const
Calendar time: month.
Definition: LCTime.h:87
CalendarTime _d
Definition: LCTime.h:120
int ns() const
Calendar time: ns.
Definition: LCTime.h:102
T setfill(T...args)
std::string getDateString() const
Date in human readable format, e.g.
Definition: LCTime.cc:220
T str(T...args)
bool isLeapYear(int y) const
True if the year is a leap year in the Gregorian calendar: year is multiple of 4 and not multiple of...
Definition: LCTime.h:66
EVENT::long64 timeStamp() const
64bit time stamp as used in LCEvent::getTimestamp().
Definition: LCTime.h:59
int day() const
Calendar time: day.
Definition: LCTime.h:90
int hour() const
Calendar time: hour.
Definition: LCTime.h:93
int min() const
Calendar time: min.
Definition: LCTime.h:96
#define SPH
Definition: LCTime.cc:14
void operator+=(EVENT::long64 t)
Add the specified number of ns to the time.
Definition: LCTime.cc:213
static bool test(int nDates)
Tests the LCTime class with nDates random dates Returns true if successful - throws Exception in case...
Definition: LCTime.cc:244
LCTime()
Init with current time ( accuracy depends on OS/machine,etc.) in UTC/GMT.
Definition: LCTime.cc:30
static const int dpm[13]
Definition: LCTime.h:128
#define DPY
Definition: LCTime.cc:17
Helper struct that holds the calendar time.
Definition: LCTime.h:24
#define YEAR0
Definition: LCTime.cc:10
void convertFromCalTime()
Definition: LCTime.cc:165
int daysInYear(int y) const
The number if days in the given year in the Gregorian calendar.
Definition: LCTime.cc:196