diff options
Diffstat (limited to 'debian/htdig/htdig-3.2.0b6/htlib/HtDateTime.cc')
-rw-r--r-- | debian/htdig/htdig-3.2.0b6/htlib/HtDateTime.cc | 1419 |
1 files changed, 1419 insertions, 0 deletions
diff --git a/debian/htdig/htdig-3.2.0b6/htlib/HtDateTime.cc b/debian/htdig/htdig-3.2.0b6/htlib/HtDateTime.cc new file mode 100644 index 00000000..3ab40e47 --- /dev/null +++ b/debian/htdig/htdig-3.2.0b6/htlib/HtDateTime.cc @@ -0,0 +1,1419 @@ +// +// HtDateTime.cc +// +// HtDateTime: Parse, split, compare and format dates and times. +// Uses locale. +// +// Part of the ht://Dig package <http://www.htdig.org/> +// Copyright (c) 1999-2004 The ht://Dig Group +// For copyright details, see the file COPYING in your distribution +// or the GNU Library General Public License (LGPL) version 2 or later +// <http://www.gnu.org/copyleft/lgpl.html> +// +// $Id: HtDateTime.cc,v 1.20 2004/05/28 13:15:20 lha Exp $ +// + +#ifdef HAVE_CONFIG_H +#include "htconfig.h" +#endif /* HAVE_CONFIG_H */ + +#include "HtDateTime.h" + +#include <stdlib.h> +#include <string.h> +#include <ctype.h> + +#ifdef HAVE_STD +#include <iostream> +#ifdef HAVE_NAMESPACES +using namespace std; +#endif +#else +#include <iostream.h> +#endif /* HAVE_STD */ + +#ifndef HAVE_STRPTIME +// mystrptime() declared in lib.h, defined in htlib/strptime.cc +#define strptime(s,f,t) mystrptime(s,f,t) +#else /* HAVE_STRPTIME */ +#ifndef HAVE_STRPTIME_DECL +extern "C" { +extern char *strptime(const char *__s, const char *__fmt, struct tm *__tp); +} +#endif /* HAVE_STRPTIME_DECL */ +#endif /* HAVE_STRPTIME */ + +/////// + // Static local variable : Visible only here !!! +/////// + +#define MAXSTRTIME 256 // Max length of my_strtime + +static struct tm Ht_tm; +static char my_strtime[MAXSTRTIME]; + + +/////// + // Recognized Date Formats +/////// + +// RFC1123: Sun, 06 Nov 1994 08:49:37 GMT +#define RFC1123_FORMAT "%a, %d %b %Y %H:%M:%S %Z" +#define LOOSE_RFC1123_FORMAT "%d %b %Y %H:%M:%S" + +// RFC850 : Sunday, 06-Nov-94 08:49:37 GMT +#define RFC850_FORMAT "%A, %d-%b-%y %H:%M:%S %Z" +#define LOOSE_RFC850_FORMAT "%d-%b-%y %H:%M:%S" + +// ANSI C's asctime() format : Sun Nov 6 08:49:37 1994 +#define ASCTIME_FORMAT "%a %b %e %H:%M:%S %Y" +#define LOOSE_ASCTIME_FORMAT "%b %e %H:%M:%S %Y" + +// ISO8601 : 1994-11-06 08:49:37 GMT +#define ISO8601_FORMAT "%Y-%m-%d %H:%M:%S %Z" + +// ISO8601 (short version): 1994-11-06 +#define ISO8601_SHORT_FORMAT "%Y-%m-%d" + +// Timestamp : 19941106084937 +#define TIMESTAMP_FORMAT "%Y%m%d%H%M%S" + + + +/////// + // Initialization +/////// + +const int HtDateTime::days[] = { 31, 28, 31, 30, 31, 30, + 31, 31, 30, 31, 30, 31}; + + +/////// // Input Formats // /////// + +/////// + // Generalized date/time parser for "LOOSE" formats + // - converts LOOSE RFC850 or RFC1123 date string into a time value + // - converts SHORT ISO8601 date string into a time value + // - autodetects which of these formats is used + // - assumes midnight if time portion omitted + // We've had problems using strptime() and timegm() on a few platforms + // while parsing these formats, so this is an attempt to sidestep them. + // + // Returns 0 if parsing failed, or returns number of characters parsed + // in date string otherwise, and sets Ht_t field to time_t value. +/////// +#define EPOCH 1970 + +int HtDateTime::Parse(const char *date) +{ + register const char *s; + register const char *t; + int day, month, year, hour, minute, second; + + // + // Three possible time designations: + // Tuesday, 01-Jul-97 16:48:02 GMT (RFC850) + // or + // Thu, 01 May 1997 00:40:42 GMT (RFC1123) + // or + // 1997-05-01 00:40:42 GMT (ISO8601) + // + // We strip off the weekday because we don't need it, and + // because some servers send invalid weekdays! + // (Some don't even send a weekday, but we'll be flexible...) + + s = date; + while (*s && *s != ',') + s++; + if (*s) + s++; + else + s = date; + while (isspace(*s)) + s++; + + // check for ISO8601 format + month = 0; + t = s; + while (isdigit(*t)) + t++; + if (t > s && *t == '-' && isdigit(t[1])) + day = -1; + else { + // not ISO8601, so try RFC850 or RFC1123 + // get day... + if (!isdigit(*s)) + return 0; + day = 0; + while (isdigit(*s)) + day = day * 10 + (*s++ - '0'); + if (day > 31) + return 0; + while (*s == '-' || isspace(*s)) + s++; + + // get month... + // (it's ugly, but it works) + switch (*s++) { + case 'J': case 'j': + switch (*s++) { + case 'A': case 'a': + month = 1; + s++; + break; + case 'U': case 'u': + switch (*s++) { + case 'N': case 'n': + month = 6; + break; + case 'L': case 'l': + month = 7; + break; + default: + return 0; + } + break; + default: + return 0; + } + break; + case 'F': case 'f': + month = 2; + s += 2; + break; + case 'M': case 'm': + switch (*s++) { + case 'A': case 'a': + switch (*s++) { + case 'R': case 'r': + month = 3; + break; + case 'Y': case 'y': + month = 5; + break; + default: + return 0; + } + break; + default: + return 0; + } + break; + case 'A': case 'a': + switch (*s++) { + case 'P': case 'p': + month = 4; + s++; + break; + case 'U': case 'u': + month = 8; + s++; + break; + default: + return 0; + } + break; + case 'S': case 's': + month = 9; + s += 2; + break; + case 'O': case 'o': + month = 10; + s += 2; + break; + case 'N': case 'n': + month = 11; + s += 2; + break; + case 'D': case 'd': + month = 12; + s += 2; + break; + default: + return 0; + } + while (*s == '-' || isspace(*s)) + s++; + } + + // get year... + if (!isdigit(*s)) + return 0; + year = 0; + while (isdigit(*s)) + year = year * 10 + (*s++ - '0'); + if (year < 69) + year += 2000; + else if (year < 1900) + year += 1900; + else if (year >= 19100) // seen some programs do it, why not check? + year -= (19100-2000); + while (*s == '-' || isspace(*s)) + s++; + + if (day < 0) { // still don't have day, so it's ISO8601 format + // get month... + if (!isdigit(*s)) + return 0; + month = 0; + while (isdigit(*s)) + month = month * 10 + (*s++ - '0'); + if (month < 1 || month > 12) + return 0; + while (*s == '-' || isspace(*s)) + s++; + + // get day... + if (!isdigit(*s)) + return 0; + day = 0; + while (isdigit(*s)) + day = day * 10 + (*s++ - '0'); + if (day < 1 || day > 31) + return 0; + while (*s == '-' || isspace(*s)) + s++; + } + + // optionally get hour... + hour = 0; + while (isdigit(*s)) + hour = hour * 10 + (*s++ - '0'); + if (hour > 23) + return 0; + while (*s == ':' || isspace(*s)) + s++; + + // optionally get minute... + minute = 0; + while (isdigit(*s)) + minute = minute * 10 + (*s++ - '0'); + if (minute > 59) + return 0; + while (*s == ':' || isspace(*s)) + s++; + + // optionally get second... + second = 0; + while (isdigit(*s)) + second = second * 10 + (*s++ - '0'); + if (second > 59) + return 0; + while (*s == ':' || isspace(*s)) + s++; + + // Assign the new value to time_t field + // + // Calculate date as seconds since 01 Jan 1970 00:00:00 GMT + // This is based somewhat on the date calculation code in NetBSD's + // cd9660_node.c code, for which I was unable to find a reference. + // It works, though! + // + Ht_t = (time_t) (((((367L*year - 7L*(year+(month+9)/12)/4 + - 3L*(((year)+((month)+9)/12-1)/100+1)/4 + + 275L*(month)/9 + day) - + (367L*EPOCH - 7L*(EPOCH+(1+9)/12)/4 + - 3L*((EPOCH+(1+9)/12-1)/100+1)/4 + + 275L*1/9 + 1)) + * 24 + hour) * 60 + minute) * 60 + second); + + // cerr << "Date string '" << date << "' converted to time_t " + // << (int)Ht_t << ", used " << (s-date) << " characters\n"; + + return s-date; +} + +/////// + // Personalized format such as C strftime function + // Overloaded version 1 + // It ignores, for now, Time Zone values +/////// + +char *HtDateTime::SetFTime(const char *buf, const char *format) +{ + + register char *p; + register int r; + + ToGMTime(); // This must be set cos strptime always stores in GM + + p = (char *) buf; + if (*format == '%') // skip any unexpected white space + while (isspace(*p)) + p++; + + // Special handling for LOOSE/SHORT formats... + if ((strcmp((char *) format, LOOSE_RFC850_FORMAT) == 0 || + strcmp((char *) format, LOOSE_RFC1123_FORMAT) == 0 || + strcmp((char *) format, ISO8601_SHORT_FORMAT) == 0) && + (r = Parse(p)) > 0) + return p+r; + + p = (char *) strptime (p, (char *) format, & Ht_tm); + +#ifdef TEST_HTDATETIME +// ViewStructTM(& Ht_tm); +#endif + + // Assign the new value to time_t value + SetDateTime(Ht_tm); + + return p; + +} + + +/////// + // C asctime() standard format +/////// + +void HtDateTime::SetAscTime(char *s) +{ + + // Unfortunately, I cannot think of an easy test to + // see if we have a weekday *FIX* + SetFTime(s, ASCTIME_FORMAT); + +} + +/////// + // RFC1123 standard Date format + // Sun, 06 Nov 1994 08:49:37 GMT +/////// + +void HtDateTime::SetRFC1123(char *s) +{ + + // abbreviated weekday name; + // day of the month; + // abbreviated month name; + // year as ccyy; + // hour ( 00 - 23); + // minute ( 00 - 59); + // seconds ( 00 - 59); + // time zone name; + + // First, if we have it, strip off the weekday + char *stripped; + stripped = strchr(s, ','); + if (stripped) + stripped++; + else + stripped = s; + + SetFTime(stripped, LOOSE_RFC1123_FORMAT); + +} + + +/////// + // RFC850 standard Date format + // Sunday, 06-Nov-1994 08:49:37 GMT +/////// + +void HtDateTime::SetRFC850(char *s) +{ + + // weekday name; + // day of the month; + // abbreviated month name; + // year within century; + // hour ( 00 - 23); + // minute ( 00 - 59); + // seconds ( 00 - 59); + // time zone name; + + // First, if we have it, strip off the weekday + char *stripped; + stripped = strchr(s, ','); + if (stripped) + stripped++; + else + stripped = s; + + SetFTime(stripped, LOOSE_RFC850_FORMAT); + +} + + +/////// + // ISO8601 standard Date format + // 1994-11-06 08:49:37 GMT +/////// + +void HtDateTime::SetISO8601(char *s) +{ + + // year as ccyy; + // month ( 01 - 12) + // day of the month + // hour ( 00 - 23) + // minute ( 00 - 59) + // seconds ( 00 - 59); + // time zone name; + + SetFTime(s, ISO8601_FORMAT); + +} + + +/////// + // Timestamp Date format (MySQL) without timezone + // 19941106084937 +/////// + +void HtDateTime::SetTimeStamp(char *s) +{ + + // year as ccyy; + // month ( 01 - 12) + // day of the month + // hour ( 00 - 23) + // minute ( 00 - 59) + // seconds ( 00 - 59); + + SetFTime(s, TIMESTAMP_FORMAT); + +} + + +/////// + // Default date and time format for the locale +/////// + +void HtDateTime::SetDateTimeDefault(char *s) +{ + + SetFTime(s, "%c"); + +} + + + + +/////// // Output Formats // /////// + + +/////// + // Personalized format such as C strftime function + // Overloaded version 1 +/////// + +size_t HtDateTime::GetFTime(char *s, size_t max, const char *format) const +{ + // Refresh static struct tm variable + + RefreshStructTM(); + + return strftime(s, max, format, & Ht_tm); + +} + +/////// + // Personalized format such as C strftime function + // Overloaded version 2 - The best to be used outside + // for temporary uses +/////// + +char *HtDateTime::GetFTime(const char *format) const +{ + + // Invoke GetFTime overloaded method + + if(GetFTime(my_strtime, MAXSTRTIME, format)) + return (char *)my_strtime; + else return 0; + +} + +/////// + // RFC1123 standard Date format + // Sun, 06 Nov 1994 08:49:37 GMT +/////// + +char *HtDateTime::GetRFC1123() const +{ + + // abbreviated weekday name; + // day of the month; + // abbreviated month name; + // year as ccyy; + // hour ( 00 - 23); + // minute ( 00 - 59); + // seconds ( 00 - 59); + // time zone name; + + GetFTime(my_strtime, MAXSTRTIME, RFC1123_FORMAT); + + return (char *)my_strtime; + +} + +/////// + // RFC850 standard Date format + // Sunday, 06-Nov-94 08:49:37 GMT +/////// + +char *HtDateTime::GetRFC850() const +{ + + // full weekday name + // day of the month + // abbreviated month name + // year within century ( 00 - 99 ) + // hour ( 00 - 23) + // minute ( 00 - 59) + // seconds ( 00 - 59); + // time zone name; + + GetFTime(my_strtime, MAXSTRTIME, RFC850_FORMAT); + + return (char *)my_strtime; + +} + +/////// + // C asctime() standard format +/////// + +char *HtDateTime::GetAscTime() const +{ + + GetFTime(my_strtime, MAXSTRTIME, ASCTIME_FORMAT); + return (char *)my_strtime; + +} + +/////// + // ISO8601 standard Date format + // 1994-11-06 08:49:37 GMT +/////// + +char *HtDateTime::GetISO8601() const +{ + + // year as ccyy; + // month ( 01 - 12) + // day of the month + // hour ( 00 - 23) + // minute ( 00 - 59) + // seconds ( 00 - 59); + // time zone name; + + GetFTime(my_strtime, MAXSTRTIME, ISO8601_FORMAT); + + return (char *)my_strtime; + +} + +/////// + // ISO8601 standard Date format + // 1994-11-06 08:49:37 GMT +/////// + +char *HtDateTime::GetShortISO8601() const +{ + + // year as ccyy; + // month ( 01 - 12) + // day of the month + + GetFTime(my_strtime, MAXSTRTIME, ISO8601_SHORT_FORMAT); + + return (char *)my_strtime; + +} + +/////// + // Timestamp Date format (MySQL) without timezone + // 19941106084937 +/////// + +char *HtDateTime::GetTimeStamp() const +{ + + // year as ccyy; + // month ( 01 - 12) + // day of the month + // hour ( 00 - 23) + // minute ( 00 - 59) + // seconds ( 00 - 59); + + GetFTime(my_strtime, MAXSTRTIME, TIMESTAMP_FORMAT); + + return (char *)my_strtime; + +} + +/////// + // Default date and time format for the locale +/////// + +char *HtDateTime::GetDateTimeDefault() const +{ + + GetFTime(my_strtime, MAXSTRTIME, "%c"); + + return (char *)my_strtime; + +} + +/////// + // Default date format for the locale +/////// + +char *HtDateTime::GetDateDefault() const +{ + + GetFTime(my_strtime, MAXSTRTIME, "%x"); + + return (char *)my_strtime; + +} + +/////// + // Default time format for the locale +/////// + +char *HtDateTime::GetTimeDefault() const +{ + + GetFTime(my_strtime, MAXSTRTIME, "%X"); + + return (char *)my_strtime; + +} + + + +/////// + // Set the static struct tm depending on localtime status +/////// + + +void HtDateTime::RefreshStructTM() const +{ + + if(local_time) + // Setting localtime + memcpy(& Ht_tm, localtime(&Ht_t), sizeof(struct tm)); + else + // Setting UTC or GM time + memcpy(& Ht_tm , gmtime(&Ht_t), sizeof(struct tm)); + +} + + +// Set the date time from a struct tm pointer + +void HtDateTime::SetDateTime(struct tm *ptm) +{ + + if(local_time) + Ht_t = mktime(ptm); // Invoke mktime + else + Ht_t = HtTimeGM(ptm); // Invoke timegm alike function + +} + + +// Set time to now + +void HtDateTime::SettoNow() +{ + Ht_t = time(0); +} + + +// Sets date by passing specific values +// The values are reffered to the GM date time +// Return false if failed + +bool HtDateTime::SetGMDateTime ( int year, int mon, int mday, + int hour, int min, int sec) +{ + struct tm tm_tmp; + + // Year + + if ( ! isAValidYear (year) ) return false; + + if( year < 100) + year=Year_From2To4digits (year); // For further checks it's converted + + // Assigning the year + + tm_tmp.tm_year=year-1900; + + + // Month + + if( ! isAValidMonth(mon) ) return false; + + tm_tmp.tm_mon=mon-1; // Assigning the month to the structure + + + // Day + + if ( ! isAValidDay ( mday, mon, year ) ) return false; + + tm_tmp.tm_mday=mday; // Assigning the day of the month + + + + if(hour >= 0 && hour < 24) tm_tmp.tm_hour = hour; + else return false; + + if(min >= 0 && min < 60) tm_tmp.tm_min = min; + else return false; + + if(sec >= 0 && sec < 60) tm_tmp.tm_sec = sec; + else return false; + + tm_tmp.tm_yday = 0; // day of the year (to be ignored) + tm_tmp.tm_isdst = 0; // default for GM (to be ignored) + + // Now we are going to insert the new values as time_t value + // This can only be done using GM Time and so ... + + if (isLocalTime()) + { + ToGMTime(); // Change to GM Time + SetDateTime(&tm_tmp); // commit it + ToLocalTime(); // And then return to Local Time + } + else SetDateTime(&tm_tmp); // only commit it + + return true; + +} + + +/////// + // Gets a struct tm from the value stored in the object + // It's a protected method. Not visible outside the class +/////// + +struct tm &HtDateTime::GetStructTM() const +{ + RefreshStructTM(); // refresh it + + return Ht_tm; +} + + +struct tm &HtDateTime::GetGMStructTM() const +{ + GetGMStructTM (Ht_tm); + return Ht_tm; +} + +void HtDateTime::GetGMStructTM(struct tm & t) const +{ + // Directly gets gmtime value + memcpy(& t , gmtime(& Ht_t), sizeof(struct tm)); +} + + +/////// + // Is a leap year? +/////// + +bool HtDateTime::LeapYear (int y) +{ + + if(y % 400 == 0 || ( y % 100 != 0 && y % 4 == 0)) + return true; // a leap year + else + return false; // and not +} + + +/////// + // Is a valid year number? +/////// + +bool HtDateTime::isAValidYear (int y) +{ + + if(y >= 1970 && y < 2069) return true; // simple check and most likely + + if(y >= 0 && y < 100) return true; // 2 digits year number + + return false; + +} + + +/////// + // Is a valid month number? +/////// + +bool HtDateTime::isAValidMonth (int m) +{ + + if( m >= 1 && m <= 12) return true; + else return false; + +} + + +/////// + // Is a valid day? +/////// + +bool HtDateTime::isAValidDay (int d, int m, int y) +{ + + if ( ! isAValidYear (y) ) return false; // Checks for the year + + if ( ! isAValidMonth (m) ) return false; // Checks for the month + + if(m == 2) + { + + // Expands the 2 digits year number + if ( y < 100 ) y=Year_From2To4digits(y); + + if ( LeapYear (y) ) // Checks for the leap year + { + if (d >= 1 && d <= 29) return true; + else return false; + } + } + + // Acts as default + + if (d >= 1 && d <= days [m -1]) return true; + else return false; + +} + + +/////// + // Comparison methods +/////// + + +int HtDateTime::DateTimeCompare (const HtDateTime & right) const +{ + int result; + + // Let's compare the date + + result=DateCompare(right); + + if(result) return result; + + // Same date. Let's compare the time + + result=TimeCompare(right); + + return result; // Nothing more to check + +} + + +int HtDateTime::GMDateTimeCompare (const HtDateTime & right) const +{ + // We must compare the whole time_t value + + if ( * this > right) return 1; // 1st greater than 2nd + if ( * this < right) return 1; // 1st lower than 2nd + + return 0; + +} + + +int HtDateTime::DateCompare (const HtDateTime & right) const +{ + + // We must transform them in 2 struct tm variables + + struct tm tm1, tm2; + + this->GetGMStructTM (tm1); + right.GetGMStructTM (tm2); + + // Let's compare them + return DateCompare (&tm1, &tm2); + +} + + +int HtDateTime::GMDateCompare (const HtDateTime & right) const +{ + + // We must transform them in 2 struct tm variables + // both referred to GM time + + struct tm tm1, tm2; + + this->GetGMStructTM (tm1); + right.GetGMStructTM (tm2); + + // Let's compare them + return DateCompare (&tm1, &tm2); + +} + + +int HtDateTime::TimeCompare (const HtDateTime & right) const +{ + + // We must transform them in 2 struct tm variables + + struct tm tm1, tm2; + + this->GetStructTM (tm1); + right.GetStructTM (tm2); + + return TimeCompare (&tm1, &tm2); + +} + + +int HtDateTime::GMTimeCompare (const HtDateTime & right) const +{ + + // We must transform them in 2 struct tm variables + + struct tm tm1, tm2; + + // We take the GM value of the time + this->GetGMStructTM (tm1); + right.GetGMStructTM (tm2); + + return TimeCompare (&tm1, &tm2); + +} + + + +/////// + // Static methods of comparison between 2 struct tm pointers +/////// + + +/////// + // Compares only the date (ignoring the time) +/////// + +int HtDateTime::DateCompare(const struct tm *tm1, const struct tm *tm2) +{ + + // Let's check the year + + if (tm1->tm_year < tm2->tm_year) return -1; + if (tm1->tm_year > tm2->tm_year) return 1; + + // Same year. Let's check the month + if (tm1->tm_mon < tm2->tm_mon) return -1; + if (tm1->tm_mon > tm2->tm_mon) return 1; + + // Same month. Let's check the day of the month + + if (tm1->tm_mday < tm2->tm_mday) return -1; + if (tm1->tm_mday > tm2->tm_mday) return 1; + + // They are equal for the date + return 0; +} + + +/////// + // Compares only the time (ignoring the date) +/////// + +int HtDateTime::TimeCompare(const struct tm *tm1, const struct tm *tm2) +{ + + // Let's check the hour + + if (tm1->tm_hour < tm2->tm_hour) return -1; + if (tm1->tm_hour > tm2->tm_hour) return 1; + + // Same hour . Let's check the minutes + + if (tm1->tm_min < tm2->tm_min) return -1; + if (tm1->tm_min > tm2->tm_min) return 1; + + // Ooops !!! Same minute. Let's check the seconds + + if (tm1->tm_sec < tm2->tm_sec) return -1; + if (tm1->tm_sec > tm2->tm_sec) return 1; + + // They are equal for the time + return 0; +} + + +/////// + // Compares both date and time +/////// + +int HtDateTime::DateTimeCompare(const struct tm *tm1, const struct tm *tm2) +{ + + int compare_date = DateCompare(tm1, tm2); + + if(compare_date) return compare_date; // Different days + + // We are in the same day. Let's check the time + + int compare_time = TimeCompare(tm1, tm2); + if(compare_time) return compare_time; // Different time + + // Equal + return 0; +} + +time_t HtDateTime::HtTimeGM (struct tm *tm) +{ + +#if HAVE_TIMEGM + return timegm (tm); +#else + return Httimegm (tm); // timegm replacement in timegm.c + // static time_t gmtime_offset; + // tm->tm_isdst = 0; + // return __mktime_internal (tm, gmtime, &gmtime_offset); +#endif + +} + + + +// Returns the difference in seconds between two HtDateTime Objects + +int HtDateTime::GetDiff(const HtDateTime &d1, const HtDateTime &d2) +{ + + return (int) ( d1.Ht_t - d2.Ht_t ); + +} + + + + + + +/////// + // Only for test and debug +/////// + +#ifdef TEST_HTDATETIME + + +/////// + // View of struct tm fields +/////// + +void HtDateTime::ViewStructTM() +{ + // Default viewing: refresh depending on time_t value + + RefreshStructTM(); // Refresh static variable + + ViewStructTM(&Ht_tm); +} + +void HtDateTime::ViewStructTM(struct tm *ptm) +{ + + cout << "Struct TM fields" << endl; + cout << "================" << endl; + cout << "tm_sec :\t" << ptm->tm_sec << endl; + cout << "tm_min :\t" << ptm->tm_min << endl; + cout << "tm_hour :\t" << ptm->tm_hour << endl; + cout << "tm_mday :\t" << ptm->tm_mday << endl; + cout << "tm_mon :\t" << ptm->tm_mon << endl; + cout << "tm_year :\t" << ptm->tm_year << endl; + cout << "tm_wday :\t" << ptm->tm_wday << endl; + cout << "tm_yday :\t" << ptm->tm_yday << endl; + cout << "tm_isdst :\t" << ptm->tm_isdst<< endl; + +} + + + + +int HtDateTime::Test(void) +{ + + int ok=1; + + const char *test_dates[] = + { + "1970.01.01 00:00:00", + "1970.01.01 00:00:01", + "1972.02.05 23:59:59", + "1972.02.28 00:59:59", + "1972.02.28 23:59:59", + "1972.02.29 00:00:00", + "1972.03.01 13:00:04", + "1973.03.01 12:00:00", + "1980.01.01 00:00:05", + "1984.12.31 23:00:00", + "1997.06.05 17:55:35", + "1999.12.31 23:00:00", + "2000.01.01 00:00:05", + "2000.02.28 23:00:05", + "2000.02.29 23:00:05", + "2000.03.01 00:00:05", + "2007.06.05 17:55:35", + "2038.01.19 03:14:07", + 0 + }; + + const char *test_dates_ISO8601[] = + { + "1970-01-01 00:00:00 GMT", + "1970-01-01 00:00:00 CET", + "1990-02-27 23:30:20 GMT", + "1999-02-28 06:53:40 GMT", + "1975-04-27 06:53:40 CET", + 0 + }; + + const char *test_dates_RFC1123[] = + { + "Sun, 06 Nov 1994 08:49:37 GMT", + "Sun, 25 Apr 1999 17:49:37 GMT", + "Sun, 25 Apr 1999 17:49:37 CET", + 0 + }; + + const char *test_dates_RFC850[] = + { + "Sunday, 06-Nov-94 08:49:37 GMT", + "Sunday, 25-Apr-99 17:49:37 GMT", + "Sunday, 25-Apr-99 17:49:37 CET", + 0 + }; + + + const char myformat[]="%Y.%m.%d %H:%M:%S"; + + // Tests a personal format + + cout << endl << "Beginning Test of a personal format such as " + << myformat << endl << endl; + + if (Test((char **)test_dates, (const char *)myformat)) + cout << "Test OK." << endl; + else + { + cout << "Test Failed." << endl; + ok=0; + } + + + // Tests ISO 8601 Format + + cout << endl << "Beginning Test of ISO 8601 format" << endl << endl; + + if(Test((char **)test_dates_ISO8601, (const char *)ISO8601_FORMAT)) + cout << "Test OK." << endl; + else + { + cout << "Test Failed." << endl; + ok=0; + } + + + // Tests RFC 1123 Format + + cout << endl << "Beginning Test of RFC 1123 format" << endl << endl; + + if (Test((char **)test_dates_RFC1123, (const char *)RFC1123_FORMAT)) + cout << "Test OK." << endl; + else + { + cout << "Test Failed." << endl; + ok=0; + } + + + // Tests RFC 850 Format + + cout << endl << "Beginning Test of RFC 850 format" << endl << endl; + + if (Test((char **)test_dates_RFC850, (const char *)RFC850_FORMAT)) + cout << "Test OK." << endl; + else + { + cout << "Test Failed." << endl; + ok=0; + } + + + return(ok ? 1 : 0); + +} + + + +int HtDateTime::Test(char **test_dates, const char *format) +{ + int i, ok = 1; + HtDateTime orig, conv; + + for (i = 0; (test_dates[i]); i++) + { + + cout << "\t " << i+1 << "\tDate string parsing of:" << endl; + cout << "\t\t" << test_dates[i] << endl; + cout << "\t\tusing format: " << format << endl << endl; + + orig.SetFTime(test_dates[i], format); + + orig.ComparisonTest(conv); + + conv=orig; + + if (orig != conv) + { + cout << "HtDateTime test failed!" << endl; + cout << "\t Original : " << orig.GetRFC1123() << endl; + cout << "\t Converted: " << orig.GetRFC1123() << endl; + ok = 0; + } + else + { + orig.ToLocalTime(); + cout << endl << "\t Localtime viewing" << endl; + orig.ViewFormats(); + orig.ToGMTime(); + cout << endl << "\t GMtime viewing" << endl; + orig.ViewFormats(); + //orig.ViewStructTM(); + } + + cout << endl; + + } + + return ok; +} + + +void HtDateTime::ComparisonTest (const HtDateTime &right) const +{ + int result; + + + cout << "Comparison between:" << endl; + + cout << " 1. " << this->GetRFC1123() << endl; + cout << " 2. " << right.GetRFC1123() << endl; + cout << endl; + + +/////// + // Complete comparison +/////// + + cout << "\tComplete comparison (date and time)" << endl; + result = this->DateTimeCompare (right); + + cout << "\t\t " << this->GetDateTimeDefault(); + + if (result > 0 ) + cout << " is greater than "; + else if (result < 0 ) + cout << " is lower than "; + else cout << " is equal to "; + + cout << " " << right.GetDateTimeDefault() << endl; + + + +/////// + // Date comparison +/////// + + cout << "\tDate comparison (ignoring time)" << endl; + result = this->DateCompare (right); + + cout << "\t\t " << this->GetDateDefault(); + + if (result > 0 ) + cout << " is greater than "; + else if (result < 0 ) + cout << " is lower than "; + else cout << " is equal to "; + + cout << " " << right.GetDateDefault() << endl; + + +/////// + // Date comparison (after GM time conversion) +/////// + + cout << "\tDate comparison (ignoring time) - GM time conversion" << endl; + result = this->GMDateCompare (right); + + cout << "\t\t " << this->GetDateDefault(); + + if (result > 0 ) + cout << " is greater than "; + else if (result < 0 ) + cout << " is lower than "; + else cout << " is equal to "; + + cout << " " << right.GetDateDefault() << endl; + + + +/////// + // Time comparison +/////// + + cout << "\tTime comparison (ignoring date)" << endl; + result = this->TimeCompare (right); + + cout << "\t\t " << this->GetTimeDefault(); + + if (result > 0 ) + cout << " is greater than "; + else if (result < 0 ) + cout << " is lower than "; + else cout << " is equal to "; + + cout << " " << right.GetTimeDefault() << endl; + + +/////// + // Time comparison (after GM time conversion) +/////// + + cout << "\tTime comparison (ignoring date) - GM time conversion" << endl; + result = this->GMTimeCompare (right); + + cout << "\t\t " << this->GetTimeDefault(); + + if (result > 0 ) + cout << " is greater than "; + else if (result < 0 ) + cout << " is lower than "; + else cout << " is equal to "; + + cout << " " << right.GetTimeDefault() << endl; + +} + + + +void HtDateTime::ViewFormats() +{ + + cout << "\t\t RFC 1123 Format : " << GetRFC1123() << endl; + cout << "\t\t RFC 850 Format : " << GetRFC850() << endl; + cout << "\t\t C Asctime Format: " << GetAscTime() << endl; + cout << "\t\t ISO 8601 Format : " << GetISO8601() << endl; + +} + +#endif |