You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1064 lines
25 KiB
C++

/***************************************************************************
* Copyright (C) 2009 by gempa GmbH *
* *
* All Rights Reserved. *
* *
* NOTICE: All information contained herein is, and remains *
* the property of gempa GmbH and its suppliers, if any. The intellectual *
* and technical concepts contained herein are proprietary to gempa GmbH *
* and its suppliers. *
* Dissemination of this information or reproduction of this material *
* is strictly forbidden unless prior written permission is obtained *
* from gempa GmbH. *
***************************************************************************/
#include <gempa/caps/datetime.h>
#include <sstream>
#include <cmath>
#include <stdexcept>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#ifdef WIN32
#include <time.h>
#endif
using namespace std;
using namespace Gempa::CAPS;
/* We are linking against the multithreaded versions
of the Microsoft runtimes - this makes gmtime
equiv to gmtime_r in that Windows gmtime is threadsafe
*/
#if defined (WIN32)
static struct tm* gmtime_r(const time_t *timep, struct tm* result)
{
struct tm *local;
local = gmtime(timep);
memcpy(result,local,sizeof(struct tm));
return result;
}
#endif
#if defined(WIN32)
#if defined(_MSC_VER) || defined(_MSC_EXTENSIONS)
#define DELTA_EPOCH_IN_MICROSECS 11644473600000000Ui64
#else
#define DELTA_EPOCH_IN_MICROSECS 11644473600000000ULL
#endif
struct timezone
{
int tz_minuteswest; /* minutes W of Greenwich */
int tz_dsttime; /* type of dst correction */
};
int gettimeofday(struct timeval *tv, struct timezone *tz)
{
FILETIME ft;
unsigned __int64 tmpres = 0;
static int tzflag;
if (NULL != tv)
{
GetSystemTimeAsFileTime(&ft);
tmpres |= ft.dwHighDateTime;
tmpres <<= 32;
tmpres |= ft.dwLowDateTime;
/*converting file time to unix epoch*/
tmpres /= 10; /*convert into microseconds*/
tmpres -= DELTA_EPOCH_IN_MICROSECS;
tv->tv_sec = (long)(tmpres / 1000000UL);
tv->tv_usec = (long)(tmpres % 1000000UL);
}
if (NULL != tz)
{
if (!tzflag)
{
_tzset();
tzflag++;
}
tz->tz_minuteswest = _timezone / 60;
tz->tz_dsttime = _daylight;
}
return 0;
}
#endif
#if defined(WIN32)
extern "C" {
#include "strptime.h"
}
#endif
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
#define MICROS 1000000
namespace {
#ifdef __sun__
#define NO_COMPACT_DATE
#endif
#if defined(__SUNPRO_CC) || defined(__sun__) || defined(WIN32)
time_t timegm(struct tm *t) {
time_t tl, tb;
struct tm tg;
t->tm_isdst = 0;
tl = mktime (t);
if (tl == -1) {
t->tm_hour--;
tl = mktime (t);
if (tl == -1)
return -1; /* can't deal with output from strptime */
tl += 3600;
}
gmtime_r(&tl, &tg);
tg.tm_isdst = 0;
tb = mktime(&tg);
if (tb == -1) {
--tg.tm_hour;
tb = mktime(&tg);
if (tb == -1)
return -1; /* can't deal with output from gmtime */
tb += 3600;
}
return (tl - (tb - tl));
}
#endif
template <typename T, typename U>
inline void normalize(T &sec, U &usec) {
if ( usec < 0 ) {
if ( sec > 0 || usec <= -MICROS ) {
usec += MICROS;
sec -= 1;
}
}
else if ( usec > 0 ) {
if ( sec < 0 || usec >= MICROS ) {
usec -= MICROS;
sec += 1;
}
}
}
}
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
TimeSpan::TimeSpan() {
_timeval.tv_sec = 0;
_timeval.tv_usec = 0;
}
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
TimeSpan::TimeSpan(struct timeval* t) {
if ( t != NULL ) {
_timeval.tv_sec = t->tv_sec;
_timeval.tv_usec = t->tv_usec;
}
else {
_timeval.tv_sec = 0;
_timeval.tv_usec = 0;
}
}
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
TimeSpan::TimeSpan(const struct timeval& t) {
_timeval.tv_sec = t.tv_sec;
_timeval.tv_usec = t.tv_usec;
}
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
TimeSpan::TimeSpan(double t) {
*this = t;
}
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
TimeSpan::TimeSpan(long secs, long usecs) {
_timeval.tv_sec = secs + (usecs / MICROS);
_timeval.tv_usec = usecs % MICROS;
}
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
TimeSpan::TimeSpan(const TimeSpan& ts) {
_timeval.tv_sec = ts._timeval.tv_sec;
_timeval.tv_usec = ts._timeval.tv_usec;
}
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
bool TimeSpan::operator==(const TimeSpan& t) const {
return _timeval.tv_sec == t._timeval.tv_sec &&
_timeval.tv_usec == t._timeval.tv_usec;
}
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
bool TimeSpan::operator!=(const TimeSpan& t) const {
return !(*this == t);
}
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
bool TimeSpan::operator< (const TimeSpan& t) const {
if ( _timeval.tv_sec > t._timeval.tv_sec )
return false;
if ( _timeval.tv_sec < t._timeval.tv_sec )
return true;
return _timeval.tv_usec < t._timeval.tv_usec;
}
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
bool TimeSpan::operator<=(const TimeSpan& t) const {
if ( _timeval.tv_sec > t._timeval.tv_sec )
return false;
if ( _timeval.tv_sec < t._timeval.tv_sec )
return true;
return _timeval.tv_usec <= t._timeval.tv_usec;
}
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
bool TimeSpan::operator> (const TimeSpan& t) const {
if ( _timeval.tv_sec < t._timeval.tv_sec )
return false;
if ( _timeval.tv_sec > t._timeval.tv_sec )
return true;
return _timeval.tv_usec > t._timeval.tv_usec;
}
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
bool TimeSpan::operator>=(const TimeSpan& t) const {
if ( _timeval.tv_sec < t._timeval.tv_sec )
return false;
if ( _timeval.tv_sec > t._timeval.tv_sec )
return true;
return _timeval.tv_usec >= t._timeval.tv_usec;
}
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
TimeSpan::operator double() const {
return (double)_timeval.tv_sec +
(double)_timeval.tv_usec * 0.000001;
}
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
TimeSpan::operator const timeval&() const {
return _timeval;
}
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
TimeSpan& TimeSpan::operator=(long t) {
_timeval.tv_sec = t;
_timeval.tv_usec = 0;
return *this;
}
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
TimeSpan& TimeSpan::operator=(double t) {
if( t > (double)0x7fffffff || t < -(double)0x80000000 )
throw overflow_error("TimeSpan::operator=(): double doesn't fit int");
_timeval.tv_sec = (long)t;
_timeval.tv_usec = (long)((t-_timeval.tv_sec)*MICROS + 0.5);
return *this;
}
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
TimeSpan TimeSpan::operator+(const TimeSpan& t) const {
long diff_usec = _timeval.tv_usec + t._timeval.tv_usec;
long int sec = _timeval.tv_sec + t._timeval.tv_sec;
normalize(sec, diff_usec);
return TimeSpan(sec, diff_usec);
}
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
TimeSpan TimeSpan::operator-(const TimeSpan& t) const {
long diff_usec = _timeval.tv_usec - t._timeval.tv_usec;
long int sec = _timeval.tv_sec - t._timeval.tv_sec;
normalize(sec, diff_usec);
return TimeSpan(sec, diff_usec);
}
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
TimeSpan& TimeSpan::operator+=(const TimeSpan& t) {
_timeval.tv_sec += t._timeval.tv_sec;
_timeval.tv_usec += t._timeval.tv_usec;
normalize(_timeval.tv_sec, _timeval.tv_usec);
return *this;
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
}
TimeSpan& TimeSpan::operator-=(const TimeSpan& t) {
_timeval.tv_usec -= t._timeval.tv_usec;
_timeval.tv_sec -= t._timeval.tv_sec;
normalize(_timeval.tv_sec, _timeval.tv_usec);
return *this;
}
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
TimeSpan& TimeSpan::set(long secs) {
_timeval.tv_sec = secs;
return *this;
}
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
TimeSpan& TimeSpan::setUSecs(long usecs) {
_timeval.tv_usec = usecs % MICROS;
_timeval.tv_sec += usecs / MICROS;
return *this;
}
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>><<<<
void TimeSpan::elapsedTime(int* days, int* hours,
int* minutes, int* seconds) const
{
int elapsed = TimeSpan::seconds();
if (days)
*days = elapsed / 86400;
if (hours)
*hours = (elapsed % 86400) / 3600;
if (minutes)
*minutes = ((elapsed % 86400) % 3600) / 60;
if (seconds)
*seconds = ((elapsed % 86400) % 3600) % 60;
}
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
TimeSpan TimeSpan::abs() const {
return TimeSpan(::abs(_timeval.tv_sec), ::abs(_timeval.tv_usec));
}
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
double TimeSpan::length() const {
return double(*this);
}
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
long TimeSpan::seconds() const {
return _timeval.tv_sec;
}
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
long TimeSpan::microseconds() const {
return _timeval.tv_usec;
}
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
const Time Time::Null(0,0);
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
Time::Time() : TimeSpan() {
}
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
Time::Time(const TimeSpan& ts)
: TimeSpan(ts) {
}
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
Time::Time(const struct timeval& t)
: TimeSpan(t) {
}
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
Time::Time(struct timeval* t)
: TimeSpan(t) {
}
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
Time::Time(double t) {
*this = t;
}
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
Time::Time(int year, int month, int day,
int hour, int min, int sec,
int usec) {
set(year, month, day, hour, min, sec, usec);
}
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
Time::Time(const Time& t)
: TimeSpan(t) {
}
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
Time::Time(long secs, long usecs)
: TimeSpan(secs, usecs) {
}
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
Time::operator bool() const {
return valid();
}
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
Time::operator time_t() const {
return (time_t)_timeval.tv_sec;
}
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
Time& Time::operator=(const struct timeval& t) {
_timeval = t;
return *this;
}
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
Time& Time::operator=(struct timeval* t) {
_timeval = *t;
return *this;
}
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
Time& Time::operator=(time_t t) {
_timeval.tv_sec = (long)t;
_timeval.tv_usec = 0;
return *this;
}
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
Time& Time::operator=(double t) {
_timeval.tv_sec = (long)t;
_timeval.tv_usec = (long)((t-(double)_timeval.tv_sec)*MICROS + 0.5);
return *this;
}
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
Time Time::operator+(const TimeSpan& t) const {
return Time((TimeSpan&)*this + t);
}
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
Time Time::operator-(const TimeSpan& ts) const {
return Time(TimeSpan::operator- (ts));
}
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
Time& Time::operator+=(const TimeSpan& ts) {
TimeSpan::operator+=(ts);
return *this;
}
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
Time& Time::operator-=(const TimeSpan& ts) {
TimeSpan::operator-=(ts);
return *this;
}
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
TimeSpan Time::operator-(const Time& ts) const {
return TimeSpan::operator-(ts);
}
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
Time& Time::set(int year, int month, int day,
int hour, int min, int sec,
int usec) {
tm t;
t.tm_year = year - 1900;
t.tm_mon = month - 1;
t.tm_mday = day;
t.tm_hour = hour;
t.tm_min = min;
t.tm_sec = sec;
t.tm_isdst = -1;
_timeval.tv_sec = (long)timegm(&t);
setUSecs(usec);
return *this;
}
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
bool Time::get(int *year, int *month, int *day,
int *hour, int *min, int *sec,
int *usec) const {
time_t time = (time_t)_timeval.tv_sec;
struct tm t;
gmtime_r(&time, &t);
if ( year ) *year = t.tm_year + 1900;
if ( month ) *month = t.tm_mon + 1;
if ( day ) *day = t.tm_mday;
if ( hour ) *hour = t.tm_hour;
if ( min ) *min = t.tm_min;
if ( sec ) *sec = t.tm_sec;
if ( usec ) *usec = _timeval.tv_usec;
return true;
}
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
bool Time::get2(int *year, int *yday, int *hour, int *min, int *sec,
int *usec) const {
time_t time = (time_t)_timeval.tv_sec;
struct tm t;
gmtime_r(&time, &t);
if ( year ) *year = t.tm_year + 1900;
if ( yday ) *yday = t.tm_yday;
if ( hour ) *hour = t.tm_hour;
if ( min ) *min = t.tm_min;
if ( sec ) *sec = t.tm_sec;
if ( usec ) *usec = _timeval.tv_usec;
return true;
}
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
Time Time::LocalTime() {
Time t;
t.localtime();
return t;
}
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
Time Time::GMT() {
Time t;
t.gmt();
return t;
}
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
Time Time::FromYearDay(int year, int year_day) {
std::stringstream ss;
ss << year << " " << year_day;
return FromString(ss.str().c_str(), "%Y %j");
}
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
Time& Time::localtime() {
gettimeofday(&_timeval, NULL);
time_t secs = (time_t)_timeval.tv_sec;
struct tm _tm;
#ifndef WIN32
_timeval.tv_sec = (long)timegm(::localtime_r(&secs, &_tm));
#else
// We use the native localtime function of windows, which is thread safe. (But it's not reentrant)
_timeval.tv_sec = (long)timegm(::localtime(&secs));
#endif
return *this;
}
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
Time& Time::gmt() {
gettimeofday(&_timeval, NULL);
time_t secs = (time_t)_timeval.tv_sec;
struct tm _tm;
#ifndef WIN32
_timeval.tv_sec = (long)mktime(::localtime_r(&secs, &_tm));
#else
// We use the native localtime function of windows, which is thread safe. (But it's not reentrant)
_timeval.tv_sec = (long)timegm(::localtime(&secs));
#endif
return *this;
}
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
Time Time::toLocalTime() const {
Time ret;
time_t secs = _timeval.tv_sec;
struct tm _tm;
#ifndef WIN32
ret._timeval.tv_sec = (long)timegm(::localtime_r(&secs, &_tm));
#else
// We use the native localtime function of windows, which is thread safe. (But it's not reentrant)
ret._timeval.tv_sec = (long)timegm(::localtime(&secs));
#endif
ret._timeval.tv_usec = _timeval.tv_usec;
return ret;
}
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
Time Time::toGMT() const {
Time ret;
time_t secs = _timeval.tv_sec;
struct tm _tm;
#ifndef WIN32
ret._timeval.tv_sec = _timeval.tv_sec - ((long)timegm(::localtime_r(&secs, &_tm)) - _timeval.tv_sec);
#else
ret._timeval.tv_sec = _timeval.tv_sec - ((long)timegm(::localtime(&secs)) - _timeval.tv_sec);
#endif
ret._timeval.tv_usec = _timeval.tv_usec;
return ret;
}
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
bool Time::valid() const {
return _timeval.tv_sec != 0 || _timeval.tv_usec != 0;
}
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
std::string Time::toString(const char* fmt) const {
#define BUFFER_SIZE 64
char data[BUFFER_SIZE];
char predata[BUFFER_SIZE];
time_t secs = (time_t)_timeval.tv_sec, usecs = _timeval.tv_usec;
tm t;
gmtime_r(&secs, &t);
const char *f = fmt, *last = fmt;
char *tgt = predata;
while ( (f = strchr(f, '%')) != NULL ) {
int specSize = 3;
char spec = *(f+1);
if ( spec == '\0' ) break;
char type = *(f+2);
if ( (spec >= 'a' && spec <= 'z') || (spec >= 'A' && spec <= 'Z') ) {
specSize = 2;
type = spec;
}
if ( type == 'f' ) {
int width = -1;
if ( spec >= '0' && spec <= '6' )
width = spec - '0';
memcpy(tgt, last, f-last);
tgt += f-last;
char number[24];
size_t numberOfDigits;
if ( usecs > 0 ) {
numberOfDigits = sprintf(number, "%06ld", usecs);
if ( width != -1 )
numberOfDigits = width;
else {
while ( number[numberOfDigits-1] == '0' ) --numberOfDigits;
}
}
else {
if ( width == -1 )
numberOfDigits = 4;
else
numberOfDigits = width;
sprintf(number, "%0*d", (int)numberOfDigits, 0);
}
memcpy(tgt, number, numberOfDigits);
tgt += numberOfDigits;
last = f+specSize;
}
#if defined(WIN32) || defined(NO_COMPACT_DATE)
else if ( type == 'F' ) {
memcpy(tgt, last, f-last);
tgt += f-last;
memcpy(tgt, "%Y-%m-%d", 8);
tgt += 8;
last = f+specSize;
}
#endif
#if defined(WIN32)
else if ( type == 'T' ) {
memcpy(tgt, last, f-last);
tgt += f-last;
memcpy(tgt, "%H:%M:%S", 8);
tgt += 8;
last = f+specSize;
}
#endif
++f;
}
strcpy(tgt, last);
strftime(data, BUFFER_SIZE-1, predata, &t);
return data;
}
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
std::string Time::iso() const {
return toString("%FT%T.%fZ");
}
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
bool Time::fromString(const char* str, const char* fmt) {
struct tm t;
char data[BUFFER_SIZE];
char tmpFmt[BUFFER_SIZE];
long usec = 0;
const char* microSeconds = strstr(fmt, "%f");
if ( microSeconds != NULL ) {
const char* start = str;
if ( microSeconds != fmt ) {
start = strrchr(str, *(microSeconds-1));
if ( start == NULL )
return false;
++start;
}
const char* end = start;
while ( *end >= '0' && *end <= '9' )
++end;
int size = end-start;
if ( size > 6 ) size = 6;
int multiplier = 100000;
char *startNumber, *endNumber;
memcpy(data, start, size);
data[size] = '\0';
for ( startNumber = data; *startNumber == '0' && *startNumber != '\0'; ++startNumber )
multiplier /= 10;
for ( endNumber = data + size-1; *endNumber == '0' && endNumber > startNumber; --endNumber )
*endNumber = '\0';
while ( endNumber-- > startNumber )
multiplier /= 10;
usec = atoi(data) * multiplier;
int len = start - str;
if ( len > BUFFER_SIZE ) {
return false;
}
memcpy(data, str, len);
data[len] = '\0';
strcat(data, "%");
strcat(data, end);
str = data;
strcpy(tmpFmt, fmt);
tmpFmt[microSeconds - fmt + 1] = '%';
fmt = tmpFmt;
}
#ifdef NO_COMPACT_DATE
char tmpFmtDate[BUFFER_SIZE];
const char* compactDate = strstr(fmt, "%F");
if ( compactDate != NULL ) {
char *dst = tmpFmtDate;
while ( fmt != compactDate ) { *dst++ = *fmt++; }
strcpy(dst, "%Y-%m-%d");
dst += 8;
fmt += 2;
while ( *fmt != '\0' ) { *dst++ = *fmt++; }
*dst = '\0';
fmt = tmpFmtDate;
}
#endif
time_t tmp_t = 0;
gmtime_r(&tmp_t, &t);
if ( strptime(str, fmt, &t) == NULL ) {
*this = (time_t)0;
return false;
}
else {
*this = timegm(&t);
setUSecs(usec);
}
return true;
#undef BUFFER_SIZE
}
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
Time Time::FromString(const char* str, const char* fmt) {
Time t;
t.fromString(str, fmt);
return t;
}