| The Gaudi Framework v30r0 (c919700c)

- 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 <cerrno>
7 #include <cstdio>
8 #include <cstring>
9 #include <ctime>
10 #include <iostream>
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 {
69 // This code is adapted from wine, samba
70 time_t t1 = mktime( t );
71 struct tm gmt;
72 gmtime_s( &gmt, &t1 );
73 time_t t2 = mktime( &gmt );
74 return t1 + ( t1 - t2 );
75 }
76 #endif
77
78 //=============================================================================
79 // Standard constructor, initializes variables
80 //=============================================================================
81 Time::Time( int year, int month, int day, int hour, int min, int sec, ValueType nsecs, bool local /* = true */ )
82 {
83 tm val;
84 memset( &val, 0, sizeof( val ) );
85 val.tm_sec = sec;
86 val.tm_min = min;
87 val.tm_hour = hour;
88 val.tm_mday = day;
89 val.tm_mon = month;
90 val.tm_year = year > 1900 ? year - 1900 : year;
91 val.tm_isdst = -1; // FIXME?
92
93 m_nsecs = build( local, val, nsecs ).m_nsecs;
94 }
95
96 #ifdef WIN32
97
99 Time Time::from( const FILETIME* systime )
100 {
101 ValueType t = ( (ValueType)systime->dwHighDateTime << 32 ) + (ValueType)systime->dwLowDateTime;
102
103 if ( t )
104 // Subtract bias (1970--1601 in 100ns), then convert to nanoseconds.
105 t = ( t - SECS_1601_TO_1970 * ( SEC_NSECS / 100 ) ) * 100;
106
107 return Time( t );
108 }
109 #endif
110
112 Time Time::current( void )
113 {
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 {
138 tm tmp( base );
139 return Time( local ? mktime( &tmp ) : timegm( &tmp ), 0 ) + diff;
140 }
141
146 tm Time::split( bool local, int* nsecpart /* = 0 */ ) const
147 {
148 if ( nsecpart ) *nsecpart = (int)( m_nsecs % SEC_NSECS );
149
150 time_t val = ( time_t )( m_nsecs / SEC_NSECS );
151
152 tm retval;
153 if ( local )
154 localtime_r( &val, &retval );
155 else
156 gmtime_r( &val, &retval );
157
158 return retval;
159 }
160
164 tm Time::utc( int* nsecpart /* = 0 */ ) const { return split( false, nsecpart ); }
165
169 tm Time::local( int* nsecpart /* = 0 */ ) const { return split( true, nsecpart ); }
170
172 int Time::year( bool local ) const { return split( local ).tm_year + 1900; }
173
175 int Time::month( bool local ) const { return split( local ).tm_mon; }
176
178 int Time::day( bool local ) const { return split( local ).tm_mday; }
179
181 int Time::hour( bool local ) const { return split( local ).tm_hour; }
182
184 int Time::minute( bool local ) const { return split( local ).tm_min; }
185
189 int Time::second( bool local ) const { return split( local ).tm_sec; }
190
194 int Time::nsecond( void ) const { return (int)( m_nsecs % SEC_NSECS ); }
195
197 int Time::weekday( bool local ) const { return split( local ).tm_wday; }
198
202 bool Time::isdst( bool local ) const { return split( local ).tm_isdst > 0; }
203
210 Time::ValueType Time::utcoffset( int* daylight /* = 0 */ ) const
211 {
212 ValueType n = 0;
213
214 #ifndef WIN32
215 tm localtm = local();
216 n = localtm.tm_gmtoff;
217 if ( daylight ) *daylight = localtm.tm_isdst;
218 #else
219 // Adapted from WINE.
220 time_t utctime = ( time_t )( m_nsecs / SEC_NSECS );
221 tm localtm;
222 localtime_s( &localtm, &utctime );
223 int savedaylight = localtm.tm_isdst;
224 tm gmt;
225 gmtime_s( &gmt, &utctime );
226
227 gmt.tm_isdst = savedaylight;
228 n = utctime - mktime( &gmt );
229
230 if ( daylight ) *daylight = savedaylight;
231 #endif
232 return n * SEC_NSECS;
233 }
234
235 #ifdef WIN32
236 // disable warning
237 // C4996: 'tzname': This function or variable may be unsafe.
238 #pragma warning( push )
239 #pragma warning( disable : 4996 )
240 #endif
241
245 const char* Time::timezone( int* daylight /* = 0 */ ) const
246 {
247 tm localtm = local();
248 if ( daylight ) *daylight = localtm.tm_isdst;
249 // extern "C" { extern char *tzname [2]; }
250 return tzname[localtm.tm_isdst > 0 ? 1 : 0];
251 }
252 #ifdef WIN32
253 #pragma warning( pop )
254 #endif
255
260 std::string Time::format( bool local, std::string spec ) const
261 {
263 std::string result;
264 tm time = split( local );
265 std::string::size_type length = 0;
266
267 // handle the special case of "%f"
268 std::string::size_type pos = spec.find( "%f" );
269 if ( std::string::npos != pos ) {
270 // Get the milliseconds string
271 std::string ms = nanoformat( 3, 3 );
272 // Replace all the occurrences of '%f' (if not preceded by '%')
273 while ( std::string::npos != pos ) {
274 if ( pos != 0 && spec[pos - 1] != '%' ) {
275 spec.replace( pos, 2, ms );
276 }
277 pos = spec.find( "%f", pos + 1 ); // search for the next occurrence
278 }
279 }
280 const int MIN_BUF_SIZE = 128;
281 do {
282 // Guess how much we'll expand. If we go wrong, we'll expand again. (with a minimum)
283 result.resize( std::max<std::string::size_type>(
284 result.size() * 2, std::max<std::string::size_type>( spec.size() * 2, MIN_BUF_SIZE ) ),
285 0 );
286 length = ::strftime( &result[0], result.size(), spec.c_str(), &time );
287 } while ( !length );
288
289 result.resize( length );
290 return result;
291 }
292
303 std::string Time::nanoformat( size_t minwidth /* = 1 */, size_t maxwidth /* = 9 */ ) const
304 {
305 TimeAssert( ( minwidth >= 1 ) && ( minwidth <= maxwidth ) && ( maxwidth <= 9 ),
306 "nanoformat options do not satisfy: 1 <= minwidth <= maxwidth <= 9" );
307
308 // Calculate the nanosecond fraction. This will be < 1000000000.
309 int value = (int)( m_nsecs % SEC_NSECS );
310
311 std::ostringstream buf;
312 buf.fill( '0' );
313 buf.width( 9 );
314 buf << value;
315 std::string out = buf.str();
316 // Find the last non-0 char before maxwidth, but after minwidth
317 // (Note: -1 and +1 are to account for difference between position and size.
318 // moreover, npos + 1 == 0, so it is correct to say that 'not found' means size of 0)
319 size_t len = out.find_last_not_of( '0', maxwidth - 1 ) + 1;
320 // Truncate the output string to at least minwidth chars
321 out.resize( std::max( len, minwidth ) );
322 return out;
323 }
324
326
327 unsigned Time::toDosDate( Time time )
328 {
329 // Use local time since DOS does too.
330 struct tm localtm = time.local();
331
332 unsigned mday = localtm.tm_mday;
333 unsigned mon = localtm.tm_mon + 1;
334 unsigned year = ( localtm.tm_year > 80 ? localtm.tm_year - 80 : 0 );
335 unsigned sec = localtm.tm_sec / 2;
336 unsigned min = localtm.tm_min;
337 unsigned hour = localtm.tm_hour;
338 return ( mday << 16 | mon << 21 | year << 25 | sec | min << 5 | hour << 11 );
339 }
340
342 Time Time::fromDosDate( unsigned dosDate )
343 {
344 // DOS times are generally local; treat it as UTC. This avoids
345 // any round-trip conversion and leaves only a presentation as an
346 // issue. Since not much can be known about the origin of the DOS
347 // times, it's generally best to present them as such (= in UTC).
348 struct tm localtm;
349 memset( &localtm, 0, sizeof( localtm ) );
350 localtm.tm_mday = ( dosDate >> 16 ) & 0x1f;
351 localtm.tm_mon = ( ( dosDate >> 21 ) & 0xf ) - 1;
352 localtm.tm_year = ( ( dosDate >> 25 ) & 0x7f ) + 80;
353 localtm.tm_hour = ( dosDate >> 11 ) & 0x1f;
354 localtm.tm_min = ( dosDate >> 5 ) & 0x3f;
355 localtm.tm_sec = ( dosDate & 0x1f ) * 2;
356 localtm.tm_isdst = -1;
357
358 return Time( mktime( &localtm ), 0 );
359 }
360
361 //=============================================================================
Gaudi::Time::ValueType
longlong ValueType
Definition: Time.h:242
Gaudi::Time::hour
int hour(bool local) const
Get the hour, numbered [0, 23].
Definition: Time.cpp:181
Gaudi::Time::Time
Time()=default
Initialize an empty (zero) time value.
Gaudi::Time::timezone
const char * timezone(int *daylight=0) const
Return the local timezone name that applies at this time value.
Definition: Time.cpp:245
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:146
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:22
Gaudi::Time::day
int day(bool local) const
Get the day of month, numbered [1,31].
Definition: Time.cpp:178
Gaudi::Time::toDosDate
static unsigned toDosDate(Time time)
Convert the Time t into a MS-DOS date format.
Definition: Time.cpp:327
Gaudi::Time::month
int month(bool local) const
Get the month, numbered [0,11].
Definition: Time.cpp:175
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:164
plotSpeedupsPyRoot.time
time
Definition: plotSpeedupsPyRoot.py:154
Gaudi::Time::current
static Time current()
Returns the current time.
Definition: Time.cpp:112
Gaudi::Time::isdst
bool isdst(bool local) const
Check whether daylight savings is in effect.
Definition: Time.cpp:202
Gaudi::Time::TimeAssert
void TimeAssert(bool cond, const std::string &msg="time assertion failed") const
Definition: Time.h:337
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:189
compareRootHistos.retval
retval
Definition: compareRootHistos.py:427
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:169
Gaudi::Time::SEC_NSECS
static const ValueType SEC_NSECS
Nanoseconds in one second.
Definition: Time.h:267
std::string
STL class.
GaudiPluginService.cpluginsvc.n
n
Definition: cpluginsvc.py:228
__longlong
Definition: Kernel.h:56
std::string::replace
T replace(T...args)
Gaudi::Time
Based on seal::Time.
Definition: Time.h:237
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:210
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:303
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:342
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:335
std::string::c_str
T c_str(T...args)
GaudiMP.FdsRegistry.msg
msg
Definition: FdsRegistry.py:8
Gaudi::Time::nsecond
int nsecond() const
Get the nanoseconds.
Definition: Time.cpp:194
Gaudi::Time::weekday
int weekday(bool local) const
Get the day of week, numbered [0,6] and starting from Sunday.
Definition: Time.cpp:197
StatusCode::FAILURE
Definition: StatusCode.h:29
std::ostringstream::fill
T fill(T...args)
Gaudi::Time::year
int year(bool local) const
Get the year.
Definition: Time.cpp:172
Gaudi::TimeSpan
Based on seal::TimeSpan.
Definition: Time.h:55
Gaudi::Units::ms
constexpr double ms
Definition: SystemOfUnits.h:136
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:260
Gaudi::Time::minute
int minute(bool local) const
Get the minute, numbered [0, 59].
Definition: Time.cpp:184