Time.cpp
Go to the documentation of this file.00001
00002
00003 #include "GaudiKernel/Time.h"
00004
00005 #include <iostream>
00006 #include <cstdio>
00007 #include <ctime>
00008 #include <cerrno>
00009 #include <cstring>
00010
00011
00012 using namespace Gaudi;
00013
00014
00015 #ifdef WIN32
00016
00017
00018 #define NOATOM
00019 #define NOGDI
00020 #define NOGDICAPMASKS
00021 #define NOMETAFILE
00022 #define NOMINMAX
00023 #define NOMSG
00024 #define NOOPENFILE
00025 #define NORASTEROPS
00026 #define NOSCROLL
00027 #define NOSOUND
00028 #define NOSYSMETRICS
00029 #define NOTEXTMETRIC
00030 #define NOWH
00031 #define NOCOMM
00032 #define NOKANJI
00033 #define NOCRYPT
00034 #define NOMCX
00035
00036 #include <windows.h>
00037
00038 #else
00039
00040
00041 #include <sys/time.h>
00042
00043 #endif
00044
00045
00046
00047
00048
00049
00050
00051 #ifdef WIN32
00052
00061
00062 # define SECS_1601_TO_1970 ((369 * 365 + 89) * 86400ui64)
00063 #endif
00064
00065 #ifdef WIN32
00066 static time_t timegm (struct tm *t) {
00067
00068 time_t t1 = mktime (t);
00069 struct tm gmt = *gmtime (&t1);
00070 time_t t2 = mktime (&gmt);
00071 return t1 + (t1 - t2);
00072 }
00073 #endif
00074
00075
00076
00077
00078 Time::Time( int year, int month, int day,
00079 int hour, int min, int sec,
00080 ValueType nsecs,
00081 bool local ) {
00082 tm val;
00083 memset (&val, sizeof (val), 0);
00084 val.tm_sec = sec;
00085 val.tm_min = min;
00086 val.tm_hour = hour;
00087 val.tm_mday = day;
00088 val.tm_mon = month;
00089 val.tm_year = year > 1900 ? year - 1900 : year;
00090 val.tm_isdst = -1;
00091
00092 m_nsecs = build (local, val, nsecs).m_nsecs;
00093 }
00094
00095 #ifdef WIN32
00096
00098 Time Time::from (const FILETIME *systime) {
00099 ValueType t = ((ValueType) systime->dwHighDateTime << 32)
00100 + (ValueType) systime->dwLowDateTime;
00101
00102 if (t)
00103
00104 t = (t - SECS_1601_TO_1970 * (SEC_NSECS/100)) * 100;
00105
00106 return Time (t);
00107 }
00108 #endif
00109
00111 Time Time::current (void) {
00112 #ifdef WIN32
00113 FILETIME ftime;
00114 GetSystemTimeAsFileTime (&ftime);
00115 return from (&ftime);
00116 #else
00117 timeval tv;
00118 if (gettimeofday (&tv, 0) != 0) {
00119 char buf[256];
00120 std::ostringstream tag,msg;
00121 tag << "errno=" << errno;
00122 if( strerror_r(errno, buf, 256) == 0 ) {
00123 msg << buf;
00124 } else {
00125 msg << "Unknown error retriving current time";
00126 }
00127 throw GaudiException(msg.str(),tag.str(),StatusCode::FAILURE);
00128 }
00129 return Time (tv.tv_sec, tv.tv_usec * 1000);
00130 #endif
00131 }
00132
00134 Time Time::build (bool local, const tm &base, TimeSpan diff ) {
00135 tm tmp (base);
00136 return Time (local ? mktime(&tmp) : timegm(&tmp), 0) + diff;
00137 }
00138
00143 tm Time::split (bool local, int *nsecpart ) const {
00144 if (nsecpart)
00145 *nsecpart = (int)(m_nsecs % SEC_NSECS);
00146
00147 time_t val = (time_t)(m_nsecs / SEC_NSECS);
00148 return *(local ? localtime (&val) : gmtime (&val));
00149 }
00150
00154 tm Time::utc (int *nsecpart ) const {
00155 return split (false, nsecpart);
00156 }
00157
00161 tm Time::local (int *nsecpart ) const {
00162 return split (true, nsecpart);
00163 }
00164
00166 int Time::year (bool local) const {
00167 return split (local).tm_year + 1900;
00168 }
00169
00171 int Time::month (bool local) const {
00172 return split (local).tm_mon;
00173 }
00174
00176 int Time::day (bool local) const {
00177 return split (local).tm_mday;
00178 }
00179
00181 int Time::hour (bool local) const {
00182 return split (local).tm_hour;
00183 }
00184
00186 int Time::minute (bool local) const {
00187 return split (local).tm_min;
00188 }
00189
00193 int Time::second (bool local) const {
00194 return split (local).tm_sec;
00195 }
00196
00200 int Time::nsecond (void) const {
00201 return (int)(m_nsecs % SEC_NSECS);
00202 }
00203
00205 int Time::weekday (bool local) const {
00206 return split (local).tm_wday;
00207 }
00208
00212 bool Time::isdst (bool local) const {
00213 return split (local).tm_isdst > 0;
00214 }
00215
00222 Time::ValueType Time::utcoffset (int *daylight ) const {
00223 ValueType n = 0;
00224
00225 #ifndef WIN32
00226 tm localtm = local ();
00227 n = localtm.tm_gmtoff;
00228 if (daylight) *daylight = localtm.tm_isdst;
00229 #else
00230
00231 time_t utctime = (time_t)(m_nsecs / SEC_NSECS);
00232 tm localtm = *localtime (&utctime);
00233 int savedaylight = localtm.tm_isdst;
00234 tm gmt = *gmtime (&utctime);
00235
00236 gmt.tm_isdst = savedaylight;
00237 n = utctime - mktime (&gmt);
00238
00239 if (daylight) *daylight = savedaylight;
00240 #endif
00241 return n * SEC_NSECS;
00242 }
00243
00248 const char * Time::timezone (int *daylight ) const {
00249 tm localtm = local ();
00250 if (daylight) *daylight = localtm.tm_isdst;
00251
00252 return tzname [localtm.tm_isdst > 0 ? 1 : 0];
00253 }
00254
00256 std::string Time::format (bool local, const std::string &spec) const {
00257
00258 std::string result;
00259 tm time = split (local);
00260 int length = 0;
00261
00262 do
00263 {
00264
00265 result.resize (result.size() ? result.size()*2 : spec.size()*2, 0);
00266 length = ::strftime (&result[0], result.size(), spec.c_str(), &time);
00267 } while (! length);
00268
00269 result.resize (length);
00270 return result;
00271 }
00272
00283 std::string Time::nanoformat (int minwidth , int maxwidth ) const {
00284 TimeAssert( (minwidth >= 1) && (minwidth <= maxwidth) && (maxwidth <= 9),
00285 "nanoformat options do not satisfy: 1 <= minwidth <= maxwidth <= 9");
00286
00287
00288 int value = (int)(m_nsecs % SEC_NSECS);
00289
00290
00291
00292 int modulus = 1;
00293 for (int i = 0; i < 9 - maxwidth; ++i)
00294 modulus *= 10;
00295
00296
00297 int rem = value % modulus;
00298 value -= rem;
00299 if (rem > modulus / 2)
00300 value += modulus;
00301
00302
00303
00304
00305
00306 char buf [10];
00307 char *p = buf + 8;
00308 sprintf (buf, "%09d", value);
00309 while (p > buf + minwidth - 1 && *p == '0')
00310 *p-- = '\0';
00311
00312 return buf;
00313 }
00314
00316
00317 unsigned Time::toDosDate (Time time) {
00318
00319 struct tm localtm = time.local ();
00320
00321 unsigned mday = localtm.tm_mday;
00322 unsigned mon = localtm.tm_mon + 1;
00323 unsigned year = (localtm.tm_year > 80 ? localtm.tm_year - 80 : 0);
00324 unsigned sec = localtm.tm_sec / 2;
00325 unsigned min = localtm.tm_min;
00326 unsigned hour = localtm.tm_hour;
00327 return (mday << 16 | mon << 21 | year << 25
00328 | sec | min << 5 | hour << 11);
00329 }
00330
00332 Time Time::fromDosDate (unsigned dosDate) {
00333
00334
00335
00336
00337 struct tm localtm;
00338 memset (&localtm, 0, sizeof (localtm));
00339 localtm.tm_mday = (dosDate >> 16) & 0x1f;
00340 localtm.tm_mon = ((dosDate >> 21) & 0xf) - 1;
00341 localtm.tm_year = ((dosDate >> 25) & 0x7f) + 80;
00342 localtm.tm_hour = (dosDate >> 11) & 0x1f;
00343 localtm.tm_min = (dosDate >> 5) & 0x3f;
00344 localtm.tm_sec = (dosDate & 0x1f) * 2;
00345 localtm.tm_isdst = -1;
00346
00347 return Time (mktime (&localtm), 0);
00348 }
00349
00350