| The Gaudi Framework v28r2p1 (f1a77ff4)

- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

Time.cpp
Go to the documentation of this file.
1 // Include files
2 #include "GaudiKernel/Time.h"
3
4 #include "GaudiKernel/time_r.h"
5
6 #include <iostream>
7 #include <cstdio>
8 #include <ctime>
9 #include <cerrno>
10 #include <cstring>
11
12 // local
13 using namespace Gaudi;
14
15 // architecture dependent includes
16 #ifdef WIN32
17
18 // this turns off a lot of useless Win stuff which conflicts with Gaudi. (found empirically)
19 #define NOATOM
20 #define NOGDI
21 #define NOGDICAPMASKS
22 #define NOMETAFILE
23 #define NOMINMAX
24 #define NOMSG
25 #define NOOPENFILE
26 #define NORASTEROPS
27 #define NOSCROLL
28 #define NOSOUND
29 #define NOSYSMETRICS
30 #define NOTEXTMETRIC
31 #define NOWH
32 #define NOCOMM
33 #define NOKANJI
34 #define NOCRYPT
35 #define NOMCX
36
37 #include <windows.h>
38
39 #else
40 // Linux
41
42 #include <sys/time.h>
43
44 #endif
45
46 //-----------------------------------------------------------------------------
47 // Implementation file for class : Gaudi::Time
48 // Based on seal::Time
49 // 2005-12-15 : Marco Clemencic
50 //-----------------------------------------------------------------------------
51
52 #ifdef WIN32
53
62 //# define SECS_1601_TO_1970 ((369 * 365 + 89) * SECS_PER_DAY)
63 # define SECS_1601_TO_1970 ((369 * 365 + 89) * 86400ui64)
64 #endif
65
66 #ifdef WIN32
67 static time_t timegm (struct tm *t) {
68 // This code is adapted from wine, samba
69 time_t t1 = mktime (t);
70 struct tm gmt;
71 gmtime_s(&gmt, &t1);
72 time_t t2 = mktime(&gmt);
73 return t1 + (t1 - t2);
74 }
75 #endif
76
77 //=============================================================================
78 // Standard constructor, initializes variables
79 //=============================================================================
80 Time::Time( int year, int month, int day,
81 int hour, int min, int sec,
82 ValueType nsecs,
83 bool local /* = true */ ) {
84 tm val;
85 memset (&val, 0, sizeof (val));
86 val.tm_sec = sec;
87 val.tm_min = min;
88 val.tm_hour = hour;
89 val.tm_mday = day;
90 val.tm_mon = month;
91 val.tm_year = year > 1900 ? year - 1900 : year;
92 val.tm_isdst = -1; // FIXME?
93
94 m_nsecs = build (local, val, nsecs).m_nsecs;
95 }
96
97 #ifdef WIN32
98
100 Time Time::from (const FILETIME *systime) {
101 ValueType t = ((ValueType) systime->dwHighDateTime << 32)
102 + (ValueType) systime->dwLowDateTime;
103
104 if (t)
105 // Subtract bias (1970--1601 in 100ns), then convert to nanoseconds.
106 t = (t - SECS_1601_TO_1970 * (SEC_NSECS/100)) * 100;
107
108 return Time (t);
109 }
110 #endif
111
113 Time Time::current (void) {
114 #ifdef WIN32
115 FILETIME ftime;
116 GetSystemTimeAsFileTime (&ftime);
117 return from (&ftime);
118 #else
119 timeval tv;
120 if (gettimeofday (&tv, nullptr) != 0) {
121 char buf[256];
122 std::ostringstream tag,msg;
123 tag << "errno=" << errno;
124 if( strerror_r(errno, buf, 256) == 0 ) {
125 msg << buf;
126 } else {
127 msg << "Unknown error retrieving current time";
128 }
129 throw GaudiException(msg.str(),tag.str(),StatusCode::FAILURE);
130 }
131 return Time (tv.tv_sec, tv.tv_usec * 1000);
132 #endif
133 }
134
136 Time Time::build (bool local, const tm &base, TimeSpan diff /* = 0 */) {
137 tm tmp (base);
138 return Time (local ? mktime(&tmp) : timegm(&tmp), 0) + diff;
139 }
140
145 tm Time::split (bool local, int *nsecpart /* = 0 */) const {
146 if (nsecpart)
147 *nsecpart = (int)(m_nsecs % SEC_NSECS);
148
149 time_t val = (time_t)(m_nsecs / SEC_NSECS);
150
151 tm retval;
152 if (local)
153 localtime_r(&val, &retval);
154 else
155 gmtime_r(&val, &retval);
156
157 return retval;
158 }
159
163 tm Time::utc (int *nsecpart /* = 0 */) const {
164 return split (false, nsecpart);
165 }
166
170 tm Time::local (int *nsecpart /* = 0 */) const {
171 return split (true, nsecpart);
172 }
173
175 int Time::year (bool local) const {
176 return split (local).tm_year + 1900;
177 }
178
180 int Time::month (bool local) const {
181 return split (local).tm_mon;
182 }
183
185 int Time::day (bool local) const {
186 return split (local).tm_mday;
187 }
188
190 int Time::hour (bool local) const {
191 return split (local).tm_hour;
192 }
193
195 int Time::minute (bool local) const {
196 return split (local).tm_min;
197 }
198
202 int Time::second (bool local) const {
203 return split (local).tm_sec;
204 }
205
209 int Time::nsecond (void) const {
210 return (int)(m_nsecs % SEC_NSECS);
211 }
212
214 int Time::weekday (bool local) const {
215 return split (local).tm_wday;
216 }
217
221 bool Time::isdst (bool local) const {
222 return split (local).tm_isdst > 0;
223 }
224
231 Time::ValueType Time::utcoffset (int *daylight /* = 0 */) const {
232 ValueType n = 0;
233
234 #ifndef WIN32
235 tm localtm = local ();
236 n = localtm.tm_gmtoff;
237 if (daylight) *daylight = localtm.tm_isdst;
238 #else
239 // Adapted from WINE.
240 time_t utctime = (time_t)(m_nsecs / SEC_NSECS);
241 tm localtm;
242 localtime_s(&localtm, &utctime);
243 int savedaylight = localtm.tm_isdst;
244 tm gmt;
245 gmtime_s(&gmt, &utctime);
246
247 gmt.tm_isdst = savedaylight;
248 n = utctime - mktime (&gmt);
249
250 if (daylight) *daylight = savedaylight;
251 #endif
252 return n * SEC_NSECS;
253 }
254
255 #ifdef WIN32
256 // disable warning
257 // C4996: 'tzname': This function or variable may be unsafe.
258 #pragma warning(push)
259 #pragma warning(disable:4996)
260 #endif
261
265 const char * Time::timezone (int *daylight /* = 0 */) const {
266 tm localtm = local ();
267 if (daylight) *daylight = localtm.tm_isdst;
268 // extern "C" { extern char *tzname [2]; }
269 return tzname [localtm.tm_isdst > 0 ? 1 : 0];
270 }
271 #ifdef WIN32
272 #pragma warning(pop)
273 #endif
274
279 std::string Time::format (bool local, std::string spec) const {
281 std::string result;
282 tm time = split (local);
283 std::string::size_type length = 0;
284
285 // handle the special case of "%f"
286 std::string::size_type pos = spec.find("%f");
287 if (std::string::npos != pos) {
288 // Get the milliseconds string
289 std::string ms = nanoformat(3,3);
290 // Replace all the occurrences of '%f' (if not preceded by '%')
291 while (std::string::npos != pos) {
292 if (pos != 0 && spec[pos-1] != '%') {
293 spec.replace(pos, 2, ms);
294 }
295 pos = spec.find("%f", pos + 1); // search for the next occurrence
296 }
297 }
298 const int MIN_BUF_SIZE = 128;
299 do
300 {
301 // Guess how much we'll expand. If we go wrong, we'll expand again. (with a minimum)
302 result.resize(std::max<std::string::size_type>(result.size()*2,
303 std::max<std::string::size_type>(spec.size()*2, MIN_BUF_SIZE))
304 , 0);
305 length = ::strftime (&result[0], result.size(), spec.c_str(), &time);
306 } while (! length);
307
308 result.resize (length);
309 return result;
310 }
311
322 std::string Time::nanoformat (size_t minwidth /* = 1 */, size_t maxwidth /* = 9 */) const {
323 TimeAssert( (minwidth >= 1) && (minwidth <= maxwidth) && (maxwidth <= 9),
324 "nanoformat options do not satisfy: 1 <= minwidth <= maxwidth <= 9");
325
326 // Calculate the nanosecond fraction. This will be < 1000000000.
327 int value = (int)(m_nsecs % SEC_NSECS);
328
329 std::ostringstream buf;
330 buf.fill('0');
331 buf.width(9);
332 buf << value;
333 std::string out = buf.str();
334 // Find the last non-0 char before maxwidth, but after minwidth
335 // (Note: -1 and +1 are to account for difference between position and size.
336 // moreover, npos + 1 == 0, so it is correct to say that 'not found' means size of 0)
337 size_t len = out.find_last_not_of('0', maxwidth - 1) + 1;
338 // Truncate the output string to at least minwidth chars
339 out.resize(std::max(len, minwidth));
340 return out;
341 }
342
344
345 unsigned Time::toDosDate (Time time) {
346 // Use local time since DOS does too.
347 struct tm localtm = time.local ();
348
349 unsigned mday = localtm.tm_mday;
350 unsigned mon = localtm.tm_mon + 1;
351 unsigned year = (localtm.tm_year > 80 ? localtm.tm_year - 80 : 0);
352 unsigned sec = localtm.tm_sec / 2;
353 unsigned min = localtm.tm_min;
354 unsigned hour = localtm.tm_hour;
355 return (mday << 16 | mon << 21 | year << 25
356 | sec | min << 5 | hour << 11);
357 }
358
360 Time Time::fromDosDate (unsigned dosDate) {
361 // DOS times are generally local; treat it as UTC. This avoids
362 // any round-trip conversion and leaves only a presentation as an
363 // issue. Since not much can be known about the origin of the DOS
364 // times, it's generally best to present them as such (= in UTC).
365 struct tm localtm;
366 memset (&localtm, 0, sizeof (localtm));
367 localtm.tm_mday = (dosDate >> 16) & 0x1f;
368 localtm.tm_mon = ((dosDate >> 21) & 0xf) - 1;
369 localtm.tm_year = ((dosDate >> 25) & 0x7f) + 80;
370 localtm.tm_hour = (dosDate >> 11) & 0x1f;
371 localtm.tm_min = (dosDate >> 5) & 0x3f;
372 localtm.tm_sec = (dosDate & 0x1f) * 2;
373 localtm.tm_isdst = -1;
374
375 return Time (mktime (&localtm), 0);
376 }
377
378 //=============================================================================
Gaudi::Time::ValueType
longlong ValueType
Definition: Time.h:216
Gaudi::Time::hour
int hour(bool local) const
Get the hour, numbered [0, 23].
Definition: Time.cpp:190
Gaudi::Time::timezone
const char * timezone(int *daylight=0) const
Return the local timezone name that applies at this time value.
Definition: Time.cpp:265
Gaudi::Time::split
tm split(bool local, int *nsecpart=0) const
Break up the time to the standard representation, either in UTC (if local is false) or local time (if...
Definition: Time.cpp:145
Gaudi::Time::build
static Time build(bool local, const tm &base, TimeSpan diff=0)
Construct a time from local time base and a delta diff.
Definition: Time.cpp:136
GaudiException
Define general base for Gaudi exception.
Definition: GaudiException.h:23
StatusCode::FAILURE
Definition: StatusCode.h:29
Gaudi::Time::day
int day(bool local) const
Get the day of month, numbered [1,31].
Definition: Time.cpp:185
Gaudi::Time::toDosDate
static unsigned toDosDate(Time time)
Convert the Time t into a MS-DOS date format.
Definition: Time.cpp:345
Gaudi::Time::month
int month(bool local) const
Get the month, numbered [0,11].
Definition: Time.cpp:180
Gaudi::Time::current
static Time current(void)
Returns the current time.
Definition: Time.cpp:113
Gaudi::Time::utc
tm utc(int *nsecpart=0) const
Break up the time to the standard library representation, keeping it in UTC.
Definition: Time.cpp:163
plotSpeedupsPyRoot.time
time
Definition: plotSpeedupsPyRoot.py:146
Gaudi::Time::isdst
bool isdst(bool local) const
Check whether daylight savings is in effect.
Definition: Time.cpp:221
Gaudi::Time::TimeAssert
void TimeAssert(bool cond, const std::string &msg="time assertion failed") const
Definition: Time.h:298
Gaudi::Time::second
int second(bool local) const
Get the seconds, numbered [0,61] (allowing one or two leap seconds, years with leap seconds can have ...
Definition: Time.cpp:202
BrunelScenarioForwardScheduler.ms
ms
Definition: BrunelScenarioForwardScheduler.py:120
compareRootHistos.retval
retval
Definition: compareRootHistos.py:351
std::string::resize
T resize(T...args)
Gaudi::Time::local
tm local(int *nsecpart=0) const
Break up the time to the standard library representation, converting it first to local time...
Definition: Time.cpp:170
Gaudi::Time::SEC_NSECS
static const ValueType SEC_NSECS
Nanoseconds in one second.
Definition: Time.h:241
std::string
STL class.
GaudiPluginService.cpluginsvc.n
n
Definition: cpluginsvc.py:217
__longlong
Definition: Kernel.h:56
std::string::replace
T replace(T...args)
Gaudi::Time
Based on seal::Time.
Definition: Time.h:213
std::ostringstream
STL class.
std::ostringstream::width
T width(T...args)
std::mktime
T mktime(T...args)
time_r.h
std::ostringstream::str
T str(T...args)
Gaudi::Time::utcoffset
ValueType utcoffset(int *daylight=0) const
Return the number of nanoseconds that needs to be added to UTC to translate this time to the local ti...
Definition: Time.cpp:231
Gaudi::Time::nanoformat
std::string nanoformat(size_t minwidth=1, size_t maxwidth=9) const
Format the nanosecond fractional part of the time as a string.
Definition: Time.cpp:322
Time.h
std::max
T max(T...args)
Gaudi::Time::fromDosDate
static Time fromDosDate(unsigned dosDate)
Convert the MS-DOS date dosDate into a Time.
Definition: Time.cpp:360
std::string::find_last_not_of
T find_last_not_of(T...args)
std::string::find
T find(T...args)
std::string::size
T size(T...args)
Gaudi::Time::m_nsecs
ValueType m_nsecs
Definition: Time.h:296
std::string::c_str
T c_str(T...args)
GaudiMP.FdsRegistry.msg
msg
Definition: FdsRegistry.py:8
Gaudi::Time::Time
Time(void)
Initialize an empty (zero) time value.
Definition: Time.icpp:9
Gaudi::Time::weekday
int weekday(bool local) const
Get the day of week, numbered [0,6] and starting from Sunday.
Definition: Time.cpp:214
Gaudi::Time::nsecond
int nsecond(void) const
Get the nanoseconds.
Definition: Time.cpp:209
std::ostringstream::fill
T fill(T...args)
Gaudi::Time::year
int year(bool local) const
Get the year.
Definition: Time.cpp:175
Gaudi::TimeSpan
Based on seal::TimeSpan.
Definition: Time.h:56
Gaudi
Helper functions to set/get the application return code.
Definition: __init__.py:1
Gaudi::Time::format
std::string format(bool local, std::string spec="%c") const
Format the time using strftime.
Definition: Time.cpp:279
Gaudi::Time::minute
int minute(bool local) const
Get the minute, numbered [0, 59].
Definition: Time.cpp:195