// Copyright (C) 1999-2005 Open Source Telecom Corporation. // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // // As a special exception, you may use this file as part of a free software // library without restriction. Specifically, if other files instantiate // templates or use macros or inline functions from this file, or you compile // this file and link it with other files to produce an executable, this // file does not by itself cause the resulting executable to be covered by // the GNU General Public License. This exception does not however // invalidate any other reasons why the executable file might be covered by // the GNU General Public License. // // This exception applies only to the code released under the name GNU // Common C++. If you copy code from other releases into a copy of GNU // Common C++, as the General Public License permits, the exception does // not apply to the code that you add in this way. To avoid misleading // anyone as to the status of such modified files, you must delete // this exception notice from them. // // If you write modifications of your own for GNU Common C++, it is your choice // whether to permit this exception to apply to your modifications. // If you do not wish that, delete this exception notice. // #include #include #include #include #include #include #include #include #include #include #ifdef WIN32 #include "time.h" #endif #ifdef CCXX_NAMESPACES namespace ost { using namespace std; #ifdef __BORLANDC__ using std::time_t; using std::tm; using std::localtime; #endif #endif Date::Date() { time_t now = SysTime::getTime(); struct tm dt; SysTime::getLocalTime(&now, &dt); toJulian(dt.tm_year + 1900, dt.tm_mon + 1, dt.tm_mday); } Date::Date(struct tm *dt) { toJulian(dt->tm_year + 1900, dt->tm_mon + 1, dt->tm_mday); } Date::Date(time_t tm) { struct tm dt; SysTime::getLocalTime(&tm, &dt); toJulian(dt.tm_year + 1900, dt.tm_mon + 1, dt.tm_mday); } Date::Date(char *str, size_t size) { setDate(str, size); } Date::~Date() { } void Date::setDate(const char *str, size_t size) { time_t now = SysTime::getTime(); struct tm dt; SysTime::getLocalTime(&now, &dt); int year = 0; const char *mstr = str; const char *dstr = str; if(!size) size = strlen(str); //0000 if(size == 4) { #ifdef DEBUG cout << "Date::SetDate(): 0000" << endl; #endif year = dt.tm_year + 1900; mstr = str; dstr = str + 2; } //00/00 else if(size == 5) { #ifdef DEBUG cout << "Date::SetDate(): 00/00" << endl; #endif year = dt.tm_year + 1900; mstr = str; dstr = str + 3; } //000000 else if(size == 6) { #ifdef DEBUG cout << "Date::SetDate(): 000000" << endl; #endif ZNumber nyear((char*)str, 2); year = ((dt.tm_year + 1900) / 100) * 100 + nyear(); mstr = str + 2; dstr = str + 4; } //00000000 else if(size == 8 && str[2] >= '0' && str[2] <= '9' && str[5] >= '0' && str[5] <= '9') { #ifdef DEBUG cout << "Date::SetDate(): 00000000" << endl; #endif ZNumber nyear((char*)str, 4); year = nyear(); mstr = str + 4; dstr = str + 6; } //00/00/00 else if(size == 8) { #ifdef DEBUG cout << "Date::SetDate(): 00/00/00" << endl; #endif ZNumber nyear((char*)str, 2); year = ((dt.tm_year + 1900) / 100) * 100 + nyear(); mstr = str + 3; dstr = str + 6; } //0000/00/00 else if(size == 10) { #ifdef DEBUG cout << "Date::SetDate(): 0000-00-00" << endl; #endif ZNumber nyear((char*)str, 4); year = nyear(); mstr = str + 5; dstr = str + 8; } #ifdef CCXX_EXCEPTIONS else if(Thread::getException() == Thread::throwObject) { throw this; } #ifdef COMMON_STD_EXCEPTION else if(Thread::getException() == Thread::throwException) { throw Exception("Date::setDate(): Invalid date."); } #endif #endif else { julian = 0x7fffffffl; return; } ZNumber nmonth((char*)mstr, 2); ZNumber nday((char*)dstr, 2); toJulian(year, nmonth(), nday()); } Date::Date(int year, unsigned month, unsigned day) { toJulian(year, month, day); } void Date::update(void) { } bool Date::isValid(void) const { if(julian == 0x7fffffffl) return false; return true; } char *Date::getDate(char *buf) const { fromJulian(buf); return buf; } time_t Date::getDate(tm* dt) const { char buf[11]; memset(dt, 0, sizeof(tm)); fromJulian(buf); Number nyear(buf, 4); Number nmonth(buf + 5, 2); Number nday(buf + 8, 2); dt->tm_year = nyear() - 1900; dt->tm_mon = nmonth() - 1; dt->tm_mday = nday(); return mktime(dt); // to fill in day of week etc. } time_t Date::getDate(void) const { struct tm dt; return getDate(&dt); } int Date::getYear(void) const { char buf[11]; fromJulian(buf); Number num(buf, 4); return num(); } unsigned Date::getMonth(void) const { char buf[11]; fromJulian(buf); Number num(buf + 5, 2); return num(); } unsigned Date::getDay(void) const { char buf[11]; fromJulian(buf); Number num(buf + 8, 2); return num(); } unsigned Date::getDayOfWeek(void) const { return (unsigned)((julian + 1l) % 7l); } String Date::operator()() const { char buf[11]; fromJulian(buf); String date(buf); return date; } long Date::getValue(void) const { char buf[11]; fromJulian(buf); return atol(buf) * 10000 + atol(buf + 5) * 100 + atol(buf + 8); } Date& Date::operator++() { ++julian; update(); return *this; } Date& Date::operator--() { --julian; update(); return *this; } Date& Date::operator+=(const long val) { julian += val; update(); return *this; } Date& Date::operator-=(long val) { julian -= val; update(); return *this; } int Date::operator==(const Date &d) { return julian == d.julian; } int Date::operator!=(const Date &d) { return julian != d.julian; } int Date::operator<(const Date &d) { return julian < d.julian; } int Date::operator<=(const Date &d) { return julian <= d.julian; } int Date::operator>(const Date &d) { return julian > d.julian; } int Date::operator>=(const Date &d) { return julian >= d.julian; } void Date::toJulian(long year, long month, long day) { julian = 0x7fffffffl; if(month < 1 || month > 12 || day < 1 || day > 31 || year == 0) { #ifdef CCXX_EXCEPTIONS if(Thread::getException() == Thread::throwObject) { throw this; } #ifdef COMMON_STD_EXCEPTION else if(Thread::getException() == Thread::throwException) { throw Exception("Date::toJulian(): Invalid date."); } #endif #endif return; } if(year < 0) year--; julian = day - 32075l + 1461l * (year + 4800l + ( month - 14l) / 12l) / 4l + 367l * (month - 2l - (month - 14l) / 12l * 12l) / 12l - 3l * ((year + 4900l + (month - 14l) / 12l) / 100l) / 4l; } void Date::fromJulian(char *buffer) const { // The following conversion algorithm is due to // Henry F. Fliegel and Thomas C. Van Flandern: ZNumber nyear(buffer, 4); buffer[4] = '-'; ZNumber nmonth(buffer + 5, 2); buffer[7] = '-'; ZNumber nday(buffer + 8, 2); double i, j, k, l, n; l = julian + 68569.0; n = int( 4 * l / 146097.0); l = l - int( (146097.0 * n + 3)/ 4 ); i = int( 4000.0 * (l+1)/1461001.0); l = l - int(1461.0*i/4.0) + 31.0; j = int( 80 * l/2447.0); k = l - int( 2447.0 * j / 80.0); l = int(j/11); j = j+2-12*l; i = 100*(n - 49) + i + l; nyear = int(i); nmonth = int(j); nday = int(k); buffer[10] = '\0'; } Date operator+(const Date &date, const long val) { Date d = date; d.julian += val; d.update(); return d; } Date operator+(const long val, const Date &date) { Date d = date; d.julian += val; d.update(); return d; } Date operator-(const Date &date, const long val) { Date d = date; d.julian -= val; d.update(); return d; } Date operator-(const long val, const Date &date) { Date d = date; d.julian -= val; d.update(); return d; } Time::Time() { time_t now = SysTime::getTime(); struct tm dt; SysTime::getLocalTime(&now, &dt); toSeconds(dt.tm_hour, dt.tm_min, dt.tm_sec); } Time::Time(struct tm *dt) { toSeconds(dt->tm_hour, dt->tm_min, dt->tm_sec); } Time::Time(time_t tm) { struct tm dt; SysTime::getLocalTime(&tm, &dt); toSeconds(dt.tm_hour, dt.tm_min, dt.tm_sec); } Time::Time(char *str, size_t size) { setTime(str, size); } Time::Time(int hour, int minute, int second) { toSeconds(hour, minute, second); } Time::~Time() { } bool Time::isValid(void) const { if(seconds == -1) return false; return true; } char *Time::getTime(char *buf) const { fromSeconds(buf); return buf; } time_t Time::getTime(void) const { return static_cast(seconds); } int Time::getHour(void) const { char buf[7]; fromSeconds(buf); ZNumber num(buf, 2); return num(); } int Time::getMinute(void) const { char buf[7]; fromSeconds(buf); ZNumber num(buf + 2, 2); return num(); } int Time::getSecond(void) const { char buf[7]; fromSeconds(buf); ZNumber num(buf + 4, 2); return num(); } void Time::update(void) { } void Time::setTime(char *str, size_t size) { int sec = 00; if(!size) size = strlen(str); //00:00 if (size == 5) { sec = 00; } //00:00:00 else if (size == 8) { ZNumber nsecond(str + 6, 2); sec = nsecond(); } #ifdef CCXX_EXCEPTIONS else if(Thread::getException() == Thread::throwObject) { throw this; } #ifdef COMMON_STD_EXCEPTION else if(Thread::getException() == Thread::throwException) { throw Exception("Time::setTime(): Invalid time."); } #endif #endif else { return; } ZNumber nhour(str, 2); ZNumber nminute(str+3, 2); toSeconds(nhour(), nminute(), sec); } String Time::operator()() const { char buf[7]; fromSeconds(buf); String strTime(buf); return strTime; } long Time::getValue(void) const { return seconds; } Time& Time::operator++() { ++seconds; update(); return *this; } Time& Time::operator--() { --seconds; update(); return *this; } Time& Time::operator+=(const int val) { seconds += val; update(); return *this; } Time& Time::operator-=(const int val) { seconds -= val; update(); return *this; } int Time::operator==(const Time &t) { return seconds == t.seconds; } int Time::operator!=(const Time &t) { return seconds != t.seconds; } int Time::operator<(const Time &t) { return seconds < t.seconds; } int Time::operator<=(const Time &t) { return seconds <= t.seconds; } int Time::operator>(const Time &t) { return seconds > t.seconds; } int Time::operator>=(const Time &t) { return seconds >= t.seconds; } void Time::toSeconds(int hour, int minute, int second) { seconds = -1; if (hour > 23 ||minute > 59 ||second > 59) { #ifdef CCXX_EXCEPTIONS if(Thread::getException() == Thread::throwObject) { throw this; } #ifdef COMMON_STD_EXCEPTION else if(Thread::getException() == Thread::throwException) { throw Exception("Time::toSeconds(): Invalid time."); } #endif #endif return; } seconds = 3600 * hour + 60 * minute + second; } void Time::fromSeconds(char *buffer) const { ZNumber hour(buffer, 2); ZNumber minute(buffer + 2, 2); ZNumber second(buffer + 4, 2); hour = seconds / 3600; minute = (seconds - (3600 * hour())) / 60; second = seconds - (3600 * hour()) - (60 * minute()); buffer[6] = '\0'; } Time operator+(const Time &time1, const Time &time2) { Time t; t.seconds = time1.seconds + time2.seconds; t.update(); return t; } Time operator-(const Time &time1, const Time &time2) { Time t; t.seconds = time1.seconds - time2.seconds; t.update(); return t; } Time operator+(const Time &time, const int val) { Time t = time; t.seconds += val; t.update(); return t; } Time operator+(const int val, const Time &time) { Time t = time; t.seconds += val; t.update(); return t; } Time operator-(const Time &time, const int val) { Time t = time; t.seconds -= val; t.update(); return t; } Time operator-(const int val, const Time &time) { Time t = time; t.seconds -= val; t.update(); return t; } Datetime::Datetime(time_t tm) { struct tm dt; SysTime::getLocalTime(&tm, &dt); toJulian(dt.tm_year + 1900, dt.tm_mon + 1, dt.tm_mday); toSeconds(dt.tm_hour, dt.tm_min, dt.tm_sec); } Datetime::Datetime(tm *dt) : Date(dt), Time(dt) {} Datetime::Datetime(const char *a_str, size_t size) { char *timestr; if (!size) size = strlen(a_str); char *str = new char[size+1]; strncpy(str, a_str, size); str[size]=0; // 00/00 00:00 if (size == 11) { timestr = str + 6; setDate(str, 5); setTime(timestr, 5); } // 00/00/00 00:00 else if (size == 14) { timestr = str + 9; setDate(str, 8); setTime(timestr,5); } // 00/00/00 00:00:00 else if (size == 17) { timestr = str + 9; setDate(str, 8); setTime(timestr,8); } // 0000/00/00 00:00:00 else if (size == 19) { timestr = str + 11; setDate(str, 10); setTime(timestr,8); } #ifdef CCXX_EXCEPTIONS else if(Thread::getException() == Thread::throwObject) { delete str; throw this; } #ifdef COMMON_STD_EXCEPTION else if(Thread::getException() == Thread::throwException) { delete str; throw Exception("Datetime::Datetime(): Invalid time."); } #endif #endif delete str; } Datetime::Datetime(int year, unsigned month, unsigned day, int hour, int minute, int second) : Date(year, month, day), Time(hour, minute, second) {} Datetime::Datetime() : Date(), Time() { time_t now = SysTime::getTime(); struct tm dt; SysTime::getLocalTime(&now, &dt); toSeconds(dt.tm_hour, dt.tm_min, dt.tm_sec); toJulian(dt.tm_year + 1900, dt.tm_mon + 1, dt.tm_mday); } Datetime::~Datetime() { } bool Datetime::isValid(void) const { return Date::isValid() && Time::isValid(); } char *Datetime::getDatetime(char *buf) const { fromJulian(buf); buf[10] = ' '; fromSeconds(buf+11); return buf; } time_t Datetime::getDatetime(void) const { char buf[11]; struct tm dt; memset(&dt, 0, sizeof(dt)); fromJulian(buf); ZNumber nyear(buf, 4); ZNumber nmonth(buf + 5, 2); ZNumber nday(buf + 8, 2); dt.tm_year = nyear() - 1900; dt.tm_mon = nmonth() - 1; dt.tm_mday = nday(); fromSeconds(buf); ZNumber nhour(buf, 2); ZNumber nminute(buf + 2, 2); ZNumber nsecond(buf + 4, 2); dt.tm_hour = nhour(); dt.tm_min = nminute(); dt.tm_sec = nsecond(); dt.tm_isdst = -1; return mktime(&dt); } Datetime& Datetime::operator=(const Datetime datetime) { julian = datetime.julian; seconds = datetime.seconds; return *this; } Datetime& Datetime::operator+=(const Datetime &datetime) { seconds += datetime.seconds; julian += datetime.julian; Date::update(); Time::update(); return *this; } Datetime& Datetime::operator-=(const Datetime &datetime) { seconds -= datetime.seconds; julian -= datetime.julian; Date::update(); Time::update(); return *this; } Datetime& Datetime::operator+=(const Time &time) { seconds += time.getValue(); Date::update(); Time::update(); return *this; } Datetime& Datetime::operator-=(const Time &time) { seconds -= time.getValue(); Date::update(); Time::update(); return *this; } int Datetime::operator==(const Datetime &d) { return (julian == d.julian) && (seconds == d.seconds); } int Datetime::operator!=(const Datetime &d) { return (julian != d.julian) || (seconds != d.seconds); } int Datetime::operator<(const Datetime &d) { if (julian != d.julian) { return (julian < d.julian); } else { return (seconds < d.seconds); } } int Datetime::operator<=(const Datetime &d) { if (julian != d.julian) { return (julian < d.julian); } else { return (seconds <= d.seconds); } } int Datetime::operator>(const Datetime &d) { if (julian != d.julian) { return (julian > d.julian); } else { return (seconds > d.seconds); } } int Datetime::operator>=(const Datetime &d) { if (julian != d.julian) { return (julian > d.julian); } else { return (seconds >= d.seconds); } } bool Datetime::operator!() const { return !(Date::isValid() && Time::isValid()); } String Datetime::strftime(const char *format) const { char buffer[64]; size_t last; time_t t; tm tbp; String retval; t = getDatetime(); SysTime::getLocalTime(&t, &tbp); #ifdef WIN32 last = ::strftime(buffer, 64, format, &tbp); #else last = std::strftime(buffer, 64, format, &tbp); #endif buffer[last] = '\0'; retval = buffer; return retval; } DateNumber::DateNumber(char *str) : Number(str, 10), Date(str, 10) {} DateNumber::~DateNumber() {} #ifdef CCXX_NAMESPACES } #endif