00001
00002
00003
00004
00005
00006
00007
00008
00009 static const char rcsid[] __attribute__((used)) = "$Id: Time.cpp 1230 2014-11-16 02:32:01Z sella $";
00010
00011 #include "Time.h"
00012
00013 #include <time.h>
00014 #include <assert.h>
00015 #include <string.h>
00016
00017
00018 using namespace sella::util;
00019 using namespace std::chrono;
00020
00021
00022
00023
00024
00025 struct timeval Time::htontv(const struct timeval &tv) throw () {
00026 struct timeval ret_val;
00027
00028 ret_val.tv_sec = htonl(tv.tv_sec);
00029 ret_val.tv_usec = htonl(tv.tv_usec);
00030
00031 return ret_val;
00032 }
00033
00034 struct timeval Time::ntohtv(const struct timeval &tv) throw () {
00035 struct timeval ret_val;
00036
00037 ret_val.tv_sec = ntohl(tv.tv_sec);
00038 ret_val.tv_usec = ntohl(tv.tv_usec);
00039
00040 return ret_val;
00041 }
00042
00043 int Time::comparetv(const struct timeval &a, const struct timeval &b) throw () {
00044 if (a.tv_sec > b.tv_sec) {
00045 return 1;
00046 } else if (a.tv_sec < b.tv_sec) {
00047 return -1;
00048 } else if (a.tv_usec > b.tv_usec) {
00049 return 1;
00050 } else if (a.tv_usec < b.tv_usec) {
00051 return -1;
00052 }
00053
00054 return 0;
00055 }
00056
00057 void Time::cleartv(struct timeval &tv) throw () {
00058 tv = { 0, 0 };
00059 }
00060
00061 void Time::copytv(struct timeval &dst, const struct timeval &src) throw () {
00062 dst = src;
00063 }
00064
00065 void Time::subtracttv(struct timeval &dst, const struct timeval &src) throw () {
00066 if ((dst.tv_usec -= src.tv_usec) < 0) {
00067 dst.tv_usec += 1000000LL;
00068 dst.tv_sec--;
00069 }
00070 dst.tv_sec -= src.tv_sec;
00071 }
00072
00073 void Time::addtv(struct timeval &dst, const struct timeval &src) throw () {
00074 if ((dst.tv_usec -= src.tv_usec) > 1000000LL) {
00075 dst.tv_usec -= 1000000LL;
00076 dst.tv_sec++;
00077 }
00078 dst.tv_sec -= src.tv_sec;
00079 }
00080
00081 struct timespec Time::htonts(const struct timespec &ts) throw () {
00082 struct timespec ret_spec;
00083
00084 ret_spec.tv_sec = htonl(ts.tv_sec);
00085 ret_spec.tv_nsec = htonl(ts.tv_nsec);
00086
00087 return ret_spec;
00088 }
00089
00090 struct timespec Time::ntohts(const struct timespec &ts) throw () {
00091 struct timespec ret_spec;
00092
00093 ret_spec.tv_sec = ntohl(ts.tv_sec);
00094 ret_spec.tv_nsec = ntohl(ts.tv_nsec);
00095
00096 return ret_spec;
00097 }
00098
00099 int Time::comparets(const struct timespec &a, const struct timespec &b) throw () {
00100 if (a.tv_sec > b.tv_sec) {
00101 return 1;
00102 } else if (a.tv_sec < b.tv_sec) {
00103 return -1;
00104 } else if (a.tv_nsec > b.tv_nsec) {
00105 return 1;
00106 } else if (a.tv_nsec < b.tv_nsec) {
00107 return -1;
00108 }
00109
00110 return 0;
00111 }
00112
00113 void Time::clearts(struct timespec &ts) throw () {
00114 ts = { 0, 0 };
00115 }
00116
00117 void Time::copyts(struct timespec &dst, const struct timespec &src) throw () {
00118 dst = src;
00119 }
00120
00121 void Time::subtractts(struct timespec &dst, const struct timespec &src) throw () {
00122 if ((dst.tv_nsec -= src.tv_nsec) < 0) {
00123 dst.tv_nsec += 1000000000LL;
00124 dst.tv_sec--;
00125 }
00126 dst.tv_sec -= src.tv_sec;
00127 }
00128
00129 void Time::addts(struct timespec &dst, const struct timespec &src) throw () {
00130 if ((dst.tv_nsec -= src.tv_nsec) > 1000000000LL) {
00131 dst.tv_nsec -= 1000000000LL;
00132 dst.tv_sec++;
00133 }
00134 dst.tv_sec -= src.tv_sec;
00135 }
00136
00137 struct timespec Time::clock_realtime(struct timezone *tz) throw () {
00138 struct timespec now = { 0, 0 };
00139
00140 ::clock_gettime(CLOCK_REALTIME, &now);
00141
00142 return now;
00143 }
00144
00145 struct timespec Time::clock_monotonic(struct timezone *tz) throw () {
00146 struct timespec now = { 0, 0 };
00147
00148 ::clock_gettime(CLOCK_MONOTONIC, &now);
00149
00150 return now;
00151 }
00152
00153 struct timespec Time::clock_monotonic_raw(struct timezone *tz) throw () {
00154 struct timespec now = { 0, 0 };
00155
00156 ::clock_gettime(CLOCK_MONOTONIC_RAW, &now);
00157
00158 return now;
00159 }
00160
00161 struct timespec Time::clock_process_cputime_id(struct timezone *tz) throw () {
00162 struct timespec now = { 0, 0 };
00163
00164 ::clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &now);
00165
00166 return now;
00167 }
00168
00169 struct timespec Time::clock_thread_cputime_id(struct timezone *tz) throw () {
00170 struct timespec now = { 0, 0 };
00171
00172 ::clock_gettime(CLOCK_THREAD_CPUTIME_ID, &now);
00173
00174 return now;
00175 }
00176
00177 uint64_t Time::tstosec(const struct timespec &ts) throw () {
00178 return ((ts.tv_nsec / 1000000000LL) + ts.tv_sec);
00179 }
00180
00181 uint64_t Time::tstomsec(const struct timespec &ts) throw () {
00182 return ((ts.tv_nsec / 1000000LL) + (ts.tv_sec * 1000LL));
00183 }
00184
00185 uint64_t Time::tstousec(const struct timespec &ts) throw () {
00186 return (ts.tv_nsec / 1000LL + (ts.tv_sec * 1000000LL));
00187 }
00188
00189 #if 0
00190 struct timespec Time::usectots(uint64_t usec) throw () {
00191 struct timespec ret_val;
00192
00193 ret_val.tv_sec = usec / 1000;
00194 ret_val.tv_nsec = (usec % 1000) * 1000000;
00195
00196 return ret_val;
00197 }
00198
00199 struct timespec Time::msectots(const uint64_t msec) throw () {
00200 struct timespec ret_val;
00201
00202 ret_val.tv_sec = msec / 1000000;
00203 ret_val.tv_nsec = ((msec % 1000000) * 1000000);
00204
00205 return ret_val;
00206 }
00207 #endif
00208
00209 struct timespec Time::sectots(uint64_t sec) throw () {
00210 struct timespec ret_val;
00211
00212 ret_val.tv_sec = sec;
00213 ret_val.tv_nsec = 0;
00214
00215 return ret_val;
00216 }
00217
00218 std::string Time::tmtostr(const struct tm &tm, const char* format) throw () {
00219 char buf[512] = { 0 };
00220
00221 strftime(buf, sizeof(buf), format, &tm);
00222
00223 return std::string(buf);
00224 }
00225
00226 std::string Time::tstostr(const struct timespec &ts, const char* format) throw () {
00227 return sectostr(tstosec(ts), format);
00228 }
00229
00230 std::string Time::sectostr(uint64_t sec, const char* format) throw () {
00231 time_t s = (sec == 0) ? time(NULL) : sec;
00232 struct tm tm = *::localtime(&s);
00233
00234 return tmtostr(tm, format);
00235 }
00236
00237 std::string Time::msectostr(uint64_t msec, const char* format) throw () {
00238 return sectostr(msec / 1000LL, format);
00239
00240 }
00241 std::string Time::usectostr(uint64_t usec, const char* format) throw () {
00242 return sectostr(usec / 1000000LL, format);
00243 }
00244
00245 struct timeval Time::gettimeofday(struct timezone *tz) throw () {
00246 struct timeval now;
00247
00248 ::gettimeofday(&now, tz);
00249
00250 return now;
00251 }
00252
00253 uint64_t Time::gettimeofday_usec(struct timezone *tz) throw () {
00254 struct timeval now;
00255
00256 ::gettimeofday(&now, tz);
00257
00258 return tvtousec(now);
00259 }
00260
00261 uint64_t Time::gettimeofday_msec(struct timezone *tz) throw () {
00262 struct timeval now;
00263
00264 ::gettimeofday(&now, tz);
00265
00266 return tvtomsec(now);
00267 }
00268
00269 uint64_t Time::gettimeofday_sec(struct timezone *tz) throw () {
00270 struct timeval now;
00271
00272 ::gettimeofday(&now, tz);
00273
00274 return tvtosec(now);
00275 }
00276
00277 uint64_t Time::tvtousec(const struct timeval &tv) throw () {
00278 return (tv.tv_usec + (tv.tv_sec * 1000000LL));
00279 }
00280
00281 uint64_t Time::tvtomsec(const struct timeval &tv) throw () {
00282 return ((tv.tv_usec / 1000LL) + (tv.tv_sec * 1000LL));
00283 }
00284
00285 uint64_t Time::tvtosec(const struct timeval &tv) throw () {
00286 return ((tv.tv_usec / 1000000LL) + tv.tv_sec);
00287 }
00288
00289 struct timeval Time::chronototv(const std::chrono::system_clock::duration &duration) throw () {
00290 struct timeval ret_val;
00291 microseconds usec = duration_cast<microseconds>(duration);
00292
00293 if (usec <= microseconds(0)) {
00294 ret_val.tv_sec = ret_val.tv_usec = 0;
00295 } else {
00296 ret_val.tv_sec = usec.count() / 1000000LL;
00297 ret_val.tv_usec = usec.count() % 1000000LL;
00298 }
00299
00300 return ret_val;
00301 }
00302
00303 struct timeval Time::chronototv(const std::chrono::system_clock::time_point &tp) throw () {
00304 return chronototv(duration_cast<milliseconds>(tp.time_since_epoch()));
00305 }
00306
00307 struct timeval Time::sectotv(uint64_t sec) throw () {
00308 struct timeval ret_val;
00309
00310 ret_val.tv_sec = sec;
00311 ret_val.tv_usec = 0;
00312
00313 return ret_val;
00314 }
00315
00316 struct timeval Time::msectotv(uint64_t msec) throw () {
00317 struct timeval ret_val;
00318
00319 ret_val.tv_sec = msec / 1000LL;
00320 ret_val.tv_usec = ((msec % 1000LL) * 1000LL);
00321
00322 return ret_val;
00323 }
00324
00325 struct timeval Time::usectotv(uint64_t usec) throw () {
00326 struct timeval ret_val;
00327
00328 ret_val.tv_sec = usec / 1000000LL;
00329 ret_val.tv_usec = usec - (ret_val.tv_sec * 1000000LL);
00330
00331 return ret_val;
00332 }
00333
00334 struct timeval* Time::add_usectotv(struct timeval &tv, uint64_t usec) throw () {
00335 tv.tv_sec += (usec / 1000000LL);
00336 tv.tv_usec += (usec % 1000000LL);
00337
00338 if (tv.tv_usec > 1000000LL) {
00339 tv.tv_usec -= 1000000LL;
00340 tv.tv_sec++;
00341 }
00342
00343 return &tv;
00344 }
00345
00346 struct timeval* Time::add_msectotv(struct timeval &tv, uint64_t msec) throw () {
00347 tv.tv_sec += (msec / 1000LL);
00348 tv.tv_usec += ((msec % 1000LL) * 1000LL);
00349
00350 if (tv.tv_usec > 1000000LL) {
00351 tv.tv_usec -= 1000000LL;
00352 tv.tv_sec++;
00353 }
00354
00355 return &tv;
00356 }
00357
00358 struct timeval* Time::add_sectotv(struct timeval &tv, uint64_t sec) throw () {
00359 tv.tv_sec += sec;
00360
00361 if (tv.tv_usec > 1000000LL) {
00362 tv.tv_usec -= 1000000LL;
00363 tv.tv_sec++;
00364 }
00365
00366 return &tv;
00367 }
00368
00369 std::string Time::getRFC1123Date(void) throw () {
00370 static const char *days[] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };
00371 static const char *months[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
00372
00373 time_t now;
00374 struct tm tm;
00375 char buf[32];
00376
00377 time(&now);
00378 gmtime_r(&now, &tm);
00379
00380 strftime(buf, sizeof(buf), "---, %d --- %Y %H:%M:%S GMT", &tm);
00381 memcpy(buf, days[tm.tm_wday], 3);
00382 memcpy(buf + 8, months[tm.tm_mon], 3);
00383
00384 return std::string(buf);
00385 }
00386
00387
00388
00389