You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
534 lines
15 KiB
534 lines
15 KiB
3 years ago
|
//
|
||
|
// HtDateTime.h
|
||
|
//
|
||
|
// 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.h,v 1.19 2004/05/28 13:15:20 lha Exp $
|
||
|
|
||
|
///////
|
||
|
// Class for Date and Time
|
||
|
// Gabriele Bartolini - Prato - Italia
|
||
|
// Started: 22.04.1999
|
||
|
///////
|
||
|
|
||
|
// Version: 1.0
|
||
|
// Release date: 07.05.1999
|
||
|
|
||
|
//
|
||
|
// General purpose of HtDateTime
|
||
|
// The general purpose of this class, is to provide an interface for
|
||
|
// date and time managing, and to unload the programmer to manage
|
||
|
// time_t, struct tm, time system functions and other related procedures
|
||
|
// locally ... Everything regarding time and date must be put here.
|
||
|
// D'you agree with me? Well, here is a summary of the class capabilities.
|
||
|
|
||
|
// Attributes of the class:
|
||
|
//
|
||
|
// HtDateTime class has only 2 member attributes
|
||
|
// - time_t Ht_t
|
||
|
// - bool local_time
|
||
|
//
|
||
|
// Obviously Ht_t contains the most important piece of information.
|
||
|
// local_time assumes a true value if we wanna consider the date and
|
||
|
// time information as local. False means that our object value is
|
||
|
// referred to the Greenwich Meridian time.
|
||
|
|
||
|
// Interface provided:
|
||
|
//
|
||
|
// Construction:
|
||
|
// - Default: set the date time value to now
|
||
|
// - By passing a time_t value or pointer: Set to it
|
||
|
// - By passing a struct tm value or pointer: Set to it
|
||
|
// The last one could be useful sometimes. But it had better not to
|
||
|
// be used.
|
||
|
//
|
||
|
// Parsing interface:
|
||
|
// Not yet implemented ... :-)
|
||
|
//
|
||
|
// Setting Interface:
|
||
|
// - from time_t: copy the time_t value into the object
|
||
|
// - from struct tm: set the object's time_t value by converting
|
||
|
// the value from the struct tm. If local_time is set to true,
|
||
|
// converts it with mktime, else uses HtTimeGM.
|
||
|
// - set to now
|
||
|
// - from a string, by passing the input format: the method uses
|
||
|
// strptime syntax (and invokes Htstrptime). For now, timezone
|
||
|
// is ignored, and so data are stored as a GM date time value.
|
||
|
// - from an int series, by specifying all the information (year,
|
||
|
// month, day, hour, minute and second). It's all stored as
|
||
|
// GM value.
|
||
|
// - from various standard formats, such as C asctime, RFC 1123,
|
||
|
// RFC 850 (these 3 types are suggested by the HTTP/1.1 standard),
|
||
|
// ISO 8601, date and time default representation for the locale.
|
||
|
// This list could get longer ... It all depends on us.
|
||
|
// - setting the date and time to be represented in a local value
|
||
|
// or universal (GM) one.
|
||
|
//
|
||
|
// Getting Interface
|
||
|
// - in a personalized output format, by passing a string with
|
||
|
// strftime values.
|
||
|
// - in various standard formats, like C asctime, RFC 1123,
|
||
|
// RFC 850, ISO 8601 (short too), date and time default
|
||
|
// representation for the locale.
|
||
|
// - getting the time_t value
|
||
|
// - queries the local time status
|
||
|
// - getting specific piece of information of both the date and the
|
||
|
// the time, like the year, the month, the day of the week, of
|
||
|
// the year or of the month, ... In short, every kind of thing
|
||
|
// a tm structure is able to store ...
|
||
|
//
|
||
|
// Operator overloading
|
||
|
// - Copy
|
||
|
// - Every kind of logical comparison between 2 objects
|
||
|
//
|
||
|
// Comparison interface
|
||
|
// This is divided in 2 sections.
|
||
|
// - Static section:
|
||
|
// comparison are made on a 2 struct tm values basis.
|
||
|
// It's possible to compare the whole date time value, or
|
||
|
// simply the date or the time value.
|
||
|
// - Member functions section:
|
||
|
// comparison are made between 2 HtDateTime objects.
|
||
|
// You can compare either the whole date time, or the date, or the
|
||
|
// time, both as they are or referring their values to the GM value.
|
||
|
//
|
||
|
// System functions interface
|
||
|
// They are all done with previous "configure" checks
|
||
|
// - for strptime
|
||
|
// - for timegm
|
||
|
//
|
||
|
// Static methods
|
||
|
// - check for a leap year
|
||
|
// - check for a valid year number (according with time_t capabilities)
|
||
|
// - check for a valid month number
|
||
|
// - check for a valid day
|
||
|
// - converts a 2 digits year number into a 4 digits one: from 1970 to 2069.
|
||
|
// - converts a 4 digits year number into a 2 digits one.
|
||
|
// - retrieve the difference in seconds between 2 HtDateTime objs
|
||
|
//
|
||
|
// Test Interface (only by defining TEST_HTDATETIME directive).
|
||
|
//
|
||
|
|
||
|
|
||
|
#ifndef _HTDATETIME_H
|
||
|
#define _HTDATETIME_H
|
||
|
|
||
|
#ifdef HAVE_CONFIG_H
|
||
|
# include "htconfig.h"
|
||
|
#endif
|
||
|
|
||
|
#if TIME_WITH_SYS_TIME
|
||
|
#include <sys/time.h>
|
||
|
#include <time.h>
|
||
|
#else
|
||
|
# if HAVE_SYS_TIME_H
|
||
|
# include <sys/time.h>
|
||
|
# else
|
||
|
# include <time.h>
|
||
|
# endif
|
||
|
#endif
|
||
|
|
||
|
#include "htString.h"
|
||
|
|
||
|
// If you wanna do some tests
|
||
|
#define TEST_HTDATETIME
|
||
|
|
||
|
|
||
|
class HtDateTime
|
||
|
{
|
||
|
public:
|
||
|
|
||
|
///////
|
||
|
// Construction
|
||
|
///////
|
||
|
|
||
|
// Default: now and local
|
||
|
HtDateTime() {SettoNow(); ToLocalTime();}
|
||
|
|
||
|
// From an integer (seconds from epoc)
|
||
|
// Causes ambiguity in systems with time_t an integer...
|
||
|
// HtDateTime(const int i) {SetDateTime((time_t)i); ToLocalTime();}
|
||
|
|
||
|
// From a time_t value and pointer
|
||
|
HtDateTime(time_t &t) {SetDateTime(t); ToLocalTime();}
|
||
|
HtDateTime(time_t *t) {SetDateTime(t); ToLocalTime();}
|
||
|
|
||
|
// From a struct tm value and pointer
|
||
|
HtDateTime(struct tm &t) {SetDateTime(t); ToLocalTime();}
|
||
|
HtDateTime(struct tm *t) {SetDateTime(t); ToLocalTime();}
|
||
|
|
||
|
// Copy constructor
|
||
|
inline HtDateTime(const HtDateTime& rhs);
|
||
|
|
||
|
///////
|
||
|
// Interface methods
|
||
|
///////
|
||
|
|
||
|
///////
|
||
|
// "Parsing" interface
|
||
|
///////
|
||
|
|
||
|
int Parse(const char *); // It looks for the similar format
|
||
|
// then sets the date by invoking
|
||
|
// right method
|
||
|
|
||
|
|
||
|
///////
|
||
|
// "Setting" interface
|
||
|
///////
|
||
|
|
||
|
// Setting from a time_t value
|
||
|
void SetDateTime(const time_t &t) { Ht_t = t; } // by reference
|
||
|
void SetDateTime(const time_t *t) { Ht_t = *t; } // by pointer
|
||
|
|
||
|
// Set object time_t value from a struct tm
|
||
|
void SetDateTime(struct tm *); // by pointer
|
||
|
inline void SetDateTime(struct tm &t) { SetDateTime(&t);} // by reference
|
||
|
|
||
|
// Set GM Time from single values input
|
||
|
// Return true if it all went good, false else
|
||
|
bool SetGMDateTime( int year, int mon, int mday,
|
||
|
int hour=0, int min=0, int sec=0);
|
||
|
|
||
|
// Set to Now
|
||
|
void SettoNow();
|
||
|
|
||
|
// Parsing various input string format
|
||
|
// It ignores time Zone value - always stores as GM
|
||
|
char *SetFTime(const char *, const char *); // as strptime
|
||
|
|
||
|
void SetAscTime(char *); // Sun Nov 6 08:49:37 1994
|
||
|
void SetRFC1123(char *); // Sun, 06 Nov 1994 08:49:37 GMT
|
||
|
void SetRFC850(char *); // Sunday, 06-Nov-94 08:49:37 GMT
|
||
|
void SetISO8601(char *); // 1994-11-06 08:49:37 GMT
|
||
|
void SetTimeStamp(char *); // 19941106084937
|
||
|
|
||
|
void SetDateTimeDefault(char *); // Default date and time representation
|
||
|
// for the locale
|
||
|
|
||
|
///////
|
||
|
// Methods for setting Local and GM time formats (Switches)
|
||
|
///////
|
||
|
|
||
|
void ToLocalTime() {local_time=true;}
|
||
|
void ToGMTime() {local_time=false;}
|
||
|
|
||
|
|
||
|
///////
|
||
|
// "Getting" interface
|
||
|
///////
|
||
|
|
||
|
|
||
|
///////
|
||
|
// Output formats
|
||
|
///////
|
||
|
|
||
|
// Personalized output
|
||
|
char *GetFTime(const char *format) const; // as strftime
|
||
|
size_t GetFTime(char *, size_t, const char *) const; // as strftime
|
||
|
|
||
|
char *GetAscTime() const; // Sun Nov 6 08:49:37 1994
|
||
|
char *GetRFC1123() const; // Sun, 06 Nov 1994 08:49:37 GMT
|
||
|
char *GetRFC850() const; // Sunday, 06-Nov-94 08:49:37 GMT
|
||
|
char *GetISO8601() const; // 1994-11-06 08:49:37 GMT
|
||
|
char *GetTimeStamp() const; // 19941106084937
|
||
|
|
||
|
char *GetDateTimeDefault() const; // Default date and time representation
|
||
|
// for the locale
|
||
|
|
||
|
// Partial (only date or only time)
|
||
|
char *GetShortISO8601() const; // 1994-11-06
|
||
|
char *GetDateDefault() const; // Default date form for the locale
|
||
|
char *GetTimeDefault() const; // Default time form for the locale
|
||
|
|
||
|
|
||
|
///////
|
||
|
// Gets the time_t value
|
||
|
///////
|
||
|
|
||
|
time_t GetTime_t() const {return Ht_t;}
|
||
|
|
||
|
|
||
|
///////
|
||
|
// Gets specific date and time values (from a struct tm)
|
||
|
///////
|
||
|
|
||
|
// Gets the year
|
||
|
int GetYear() const { return ( GetStructTM().tm_year + 1900) ;}
|
||
|
|
||
|
// Gets the month
|
||
|
int GetMonth() const { return (GetStructTM().tm_mon + 1);}
|
||
|
|
||
|
// Gets the day of the week (since Sunday)
|
||
|
int GetWDay() const { return (GetStructTM().tm_wday + 1);}
|
||
|
|
||
|
// Gets the day of the month
|
||
|
int GetMDay() const { return GetStructTM().tm_mday;}
|
||
|
|
||
|
// Gets the day since january 1
|
||
|
int GetYDay() const { return (GetStructTM().tm_yday + 1);}
|
||
|
|
||
|
// Gets the hour
|
||
|
int GetHour() const { return GetStructTM().tm_hour;}
|
||
|
|
||
|
// Gets the minute
|
||
|
int GetMinute() const { return GetStructTM().tm_min;}
|
||
|
|
||
|
// Gets the second
|
||
|
int GetSecond() const { return GetStructTM().tm_sec;}
|
||
|
|
||
|
// Daylight saving time is in effect at that time?
|
||
|
int GetIsDst() const { return GetStructTM().tm_isdst;}
|
||
|
|
||
|
|
||
|
///////
|
||
|
// Methods for querying localtime status
|
||
|
///////
|
||
|
|
||
|
bool isLocalTime() const {return local_time;}
|
||
|
bool isGMTime() const {return !local_time;}
|
||
|
|
||
|
|
||
|
|
||
|
///////
|
||
|
// Methods for comparison
|
||
|
///////
|
||
|
|
||
|
// Returns 0 if equal, -1 if tm1 is lower than tm2, 1 if tm1 is greater than tm2
|
||
|
|
||
|
int DateTimeCompare (const HtDateTime &) const; // Compares both date and time
|
||
|
|
||
|
int DateCompare (const HtDateTime &) const; // Compares the date
|
||
|
int TimeCompare (const HtDateTime &) const; // Compares the time
|
||
|
|
||
|
// Refers the date and the time to a GM value, then compares
|
||
|
int GMDateTimeCompare (const HtDateTime &) const; // Compares both date and time
|
||
|
int GMDateCompare (const HtDateTime &) const; // Compares the date
|
||
|
int GMTimeCompare (const HtDateTime &) const; // Compares the time
|
||
|
|
||
|
|
||
|
///////
|
||
|
// Operator overloading
|
||
|
///////
|
||
|
|
||
|
// For comparisons - between objects of the same class
|
||
|
|
||
|
inline bool operator==(const HtDateTime &right) const;
|
||
|
inline bool operator<(const HtDateTime &right) const;
|
||
|
|
||
|
bool operator!=(const HtDateTime &right) const
|
||
|
{return !( *this == right );}
|
||
|
|
||
|
bool operator>=(const HtDateTime &right) const
|
||
|
{return !( *this < right);}
|
||
|
|
||
|
bool operator<=(const HtDateTime &right) const
|
||
|
{return !( right < *this);}
|
||
|
|
||
|
bool operator>(const HtDateTime &right) const
|
||
|
{return right < *this; }
|
||
|
|
||
|
|
||
|
// For comparisons - between HtDateTime objects and int
|
||
|
|
||
|
bool operator==(const int right) const // with an int
|
||
|
{return ( Ht_t == (time_t) right );}
|
||
|
|
||
|
bool operator<(const int right) const // with an int
|
||
|
{return ( Ht_t < (time_t) right );}
|
||
|
|
||
|
bool operator!=(const int right) const // with an int
|
||
|
{return !( *this == right );}
|
||
|
|
||
|
bool operator>=(const int right) const // with an int
|
||
|
{return !( *this < right);}
|
||
|
|
||
|
bool operator<=(const int right) const // with an int
|
||
|
{return !( *this > right);}
|
||
|
|
||
|
bool operator>(const int right) const // with an int
|
||
|
{return (Ht_t > (time_t) right); }
|
||
|
|
||
|
|
||
|
// For Copy
|
||
|
|
||
|
inline HtDateTime &operator=(const HtDateTime &right);
|
||
|
inline HtDateTime &operator=(const int right);
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
/////// // STATIC METHODS // ///////
|
||
|
|
||
|
// Here we can add static methods as we want more :-)
|
||
|
// Then invoke them with HtDateTime::MethodXXX ()
|
||
|
|
||
|
|
||
|
inline static bool LeapYear(int); // Is a leap year?
|
||
|
|
||
|
// These checks are made for time_t compatibility
|
||
|
inline static bool isAValidYear(int); // Is a valid year number
|
||
|
|
||
|
inline static bool isAValidMonth(int); // Is a valid month number
|
||
|
inline static bool isAValidDay(int, int, int); // Is a valid day
|
||
|
|
||
|
|
||
|
// Converts a 2 digits year in a 4 one - with no checks
|
||
|
static int Year_From2To4digits (int y)
|
||
|
{
|
||
|
if ( y >= 70 ) return y+1900;
|
||
|
else return y+2000;
|
||
|
}
|
||
|
|
||
|
// Converts a 4 digits year in a 2 one - with no checks
|
||
|
static int Year_From4To2digits (int y)
|
||
|
{
|
||
|
if ( y >= 2000 ) return y - 2000;
|
||
|
else return y - 1900;
|
||
|
}
|
||
|
|
||
|
static int GetDiff(const HtDateTime &, const HtDateTime &);
|
||
|
|
||
|
// Check equality from 2 struct tm pointers
|
||
|
// Returns 0 if equal, -1 if tm1 is lower than tm2, 1 if tm1 is greater than tm2
|
||
|
|
||
|
// Compares the whole time information (both date and time)
|
||
|
static int DateTimeCompare(const struct tm *tm1,
|
||
|
const struct tm *tm2);
|
||
|
|
||
|
// Compares only date
|
||
|
static int DateCompare(const struct tm *tm1,
|
||
|
const struct tm *tm2);
|
||
|
|
||
|
// Compares only time
|
||
|
static int TimeCompare(const struct tm *tm1,
|
||
|
const struct tm *tm2);
|
||
|
|
||
|
|
||
|
|
||
|
/////// // HIDDEN ATTRIBUTES & METHODS // ///////
|
||
|
|
||
|
protected: // to permit inheritance
|
||
|
|
||
|
time_t Ht_t;
|
||
|
bool local_time;
|
||
|
|
||
|
static const int days[];
|
||
|
|
||
|
///////
|
||
|
// Sets and gets the struct tm depending on local_time status
|
||
|
///////
|
||
|
|
||
|
void RefreshStructTM() const; // Refresh its content
|
||
|
struct tm &GetStructTM() const; // gets it
|
||
|
void GetStructTM(struct tm & t) const { t=GetStructTM(); } // Gets and copy
|
||
|
|
||
|
|
||
|
///////
|
||
|
// Gets the struct tm ignoring local_time status
|
||
|
///////
|
||
|
|
||
|
struct tm &GetGMStructTM() const; // gets it
|
||
|
void GetGMStructTM(struct tm &) const; // Gets and copy
|
||
|
|
||
|
|
||
|
///////
|
||
|
// Interface for system functions
|
||
|
///////
|
||
|
|
||
|
// Interface for timegm
|
||
|
static time_t HtTimeGM (struct tm*);
|
||
|
|
||
|
|
||
|
#ifdef TEST_HTDATETIME
|
||
|
|
||
|
///////
|
||
|
// Only for debug: view of struct tm fields
|
||
|
///////
|
||
|
|
||
|
public:
|
||
|
|
||
|
static void ViewStructTM(struct tm *); // view of struct tm fields
|
||
|
virtual void ViewStructTM(); // view of struct tm fields
|
||
|
void ViewFormats(); // View of various formats
|
||
|
|
||
|
void ComparisonTest (const HtDateTime &) const; // comparison
|
||
|
|
||
|
|
||
|
// Test of the class
|
||
|
static int Test(void);
|
||
|
static int Test(char **test_dates, const char *format);
|
||
|
|
||
|
#endif
|
||
|
|
||
|
};
|
||
|
|
||
|
|
||
|
///////
|
||
|
// Copy constructor
|
||
|
///////
|
||
|
|
||
|
inline
|
||
|
HtDateTime::HtDateTime (const HtDateTime& rhs)
|
||
|
{
|
||
|
// Copy the contents
|
||
|
Ht_t = rhs.Ht_t;
|
||
|
local_time = rhs.local_time;
|
||
|
}
|
||
|
|
||
|
///////
|
||
|
// Operator overloading
|
||
|
///////
|
||
|
|
||
|
inline
|
||
|
bool HtDateTime::operator==(const HtDateTime &right) const
|
||
|
{
|
||
|
if(Ht_t==right.Ht_t)
|
||
|
return true;
|
||
|
else
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
inline
|
||
|
bool HtDateTime::operator<(const HtDateTime &right) const
|
||
|
{
|
||
|
if(Ht_t < right.Ht_t) return true;
|
||
|
else return false;
|
||
|
}
|
||
|
|
||
|
///////
|
||
|
// Copy
|
||
|
///////
|
||
|
|
||
|
inline
|
||
|
HtDateTime &HtDateTime::operator=(const HtDateTime &right)
|
||
|
{
|
||
|
if (this != &right)
|
||
|
{
|
||
|
Ht_t=right.Ht_t; // Copy the time_t value
|
||
|
local_time=right.local_time; // Copy the local_time flag
|
||
|
}
|
||
|
|
||
|
return *this;
|
||
|
}
|
||
|
|
||
|
inline
|
||
|
HtDateTime &HtDateTime::operator=(const int right)
|
||
|
{
|
||
|
Ht_t=(time_t)right; // Copy the int as a time_t value
|
||
|
ToLocalTime();
|
||
|
return *this;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
#endif
|