/* $Revision: 26 $ $Date: 4/08/06 12:49 $ Copyright © 2000-2005, FSL Technologies Limited. Contact "http://fost3.fsltech.com". */ #ifndef FOST_TIMEDATE_HPP #define FOST_TIMEDATE_HPP #pragma once #include #ifdef F3UTIL_EXPORTS #define TIMEDATE_HPP_ARCHIVE L"$Archive: /FOST.3/F3Util/FOST.timedate.hpp $" #define TIMEDATE_HPP_REVISION L"$Revision: 26 $" #define TIMEDATE_HPP_DATE L"$Date: 4/08/06 12:49 $" #endif namespace FSLib { namespace Exceptions { class BadDate; class BadTime; class BadTimeStamp; class BadDatePeriod; class BadTimePeriod; class ReversedPeriod; } enum Day { e_monday = 0, e_tuesday, e_wednesday, e_thursday, e_friday, e_saturday, e_sunday }; inline F3UTIL_DECLSPEC std::wostream &operator <<( std::wostream &, const Day ); class TimeStamp; class DatePeriod; class BlankPeriod; template< typename T > class Period; class F3UTIL_DECLSPEC Date { public: enum t_display { e_sql, e_user_short, e_user_long, e_file_name, e_user_uk }; inline Date() throw (); inline Date( const Date & ) throw (); inline Date( int y, int m, int d, bool fixup = false ); explicit inline Date( const FSLib::wstring & ) throw (FSLib::Exceptions::BadDate); inline bool operator <( const Date & ) const throw (FSLib::Exceptions::BadDate); inline bool operator <=( const Date & ) const throw (FSLib::Exceptions::BadDate); inline bool operator >( const Date & ) const throw (FSLib::Exceptions::BadDate); inline bool operator >=( const Date & ) const throw (FSLib::Exceptions::BadDate); inline bool operator !=( const Date &t ) const throw (FSLib::Exceptions::BadDate); inline bool operator ==( const Date &t ) const throw (FSLib::Exceptions::BadDate); inline Date operator +( const DatePeriod & ) const; inline Date &operator +=( const DatePeriod & ); inline Date operator -( const DatePeriod & ) const; inline Date &operator -=( const DatePeriod & ); Day theDay() const; inline int dayOfMonth() const throw (); inline int month() const throw (); inline int year() const throw (); inline FSLib::wstring asString() const; inline FSLib::wstring asString( int ) const; inline FSLib::wstring asString( const FSLib::wstring &ymDelimiter, const FSLib::wstring &mdDelimiter ) const; inline FSLib::wstring asStringUK( const FSLib::wstring &mdDelimiter, const FSLib::wstring &ymDelimiter ) const; inline FSLib::wstring asString( t_display ) const; private: int m_year, m_month, m_date; inline void valid() const throw (FSLib::Exceptions::BadDate); inline void check() const throw (FSLib::Exceptions::BadDate); void fixup(); friend inline F3UTIL_DECLSPEC std::wostream &operator <<( std::wostream &, const Date & ); friend class TimeStamp; }; class F3UTIL_DECLSPEC Time { public: typedef double t_seconds; enum t_display { e_sql, e_user_short, e_user_long, e_file_name }; inline Time() throw (); inline Time( const Time & ) throw (); inline Time( int h, int m, t_seconds s, bool fixup = false ) throw (FSLib::Exceptions::BadTime); explicit inline Time( const FSLib::wstring & ) throw (FSLib::Exceptions::BadTime); explicit inline Time( const TimeStamp & ) throw (); inline bool operator <( const Time & ) const throw (FSLib::Exceptions::BadTime); inline bool operator <=( const Time & ) const throw (FSLib::Exceptions::BadTime); inline bool operator >( const Time & ) const throw (FSLib::Exceptions::BadTime); inline bool operator >=( const Time & ) const throw (FSLib::Exceptions::BadTime); inline bool operator !=( const Time & ) const throw (FSLib::Exceptions::BadTime); inline bool operator ==( const Time & ) const throw (FSLib::Exceptions::BadTime); inline int hour() const throw (FSLib::Exceptions::BadTime); inline int minute() const throw (FSLib::Exceptions::BadTime); inline t_seconds second() const throw (FSLib::Exceptions::BadTime); inline FSLib::wstring asString() const; inline FSLib::wstring asString( const FSLib::wstring &hmDelimiter, const FSLib::wstring &msDelimiter, const FSLib::wstring &smsDelimiter ) const; inline FSLib::wstring asString( t_display ) const; inline Time &addSeconds( const t_seconds &) throw (FSLib::Exceptions::BadTime); private: int m_hour, m_minute, m_second; inline void valid() const throw (FSLib::Exceptions::BadTime); inline void check() const throw (FSLib::Exceptions::BadTime); inline void fixup() throw (FSLib::Exceptions::BadTime); friend inline F3UTIL_DECLSPEC std::wostream &operator <<( std::wostream &, const Time & ); friend class TimeStamp; }; class TimePeriod; class F3UTIL_DECLSPEC TimeStamp { public: enum t_display { e_sql, e_file_name }; inline TimeStamp() throw (); inline TimeStamp( const TimeStamp & ) throw (); inline TimeStamp( int Y, int M, int D, int h, int m, Time::t_seconds s, bool fixup = false ); inline TimeStamp( const Date &, const Time &t ); explicit inline TimeStamp( const FSLib::wstring & ) throw (FSLib::Exceptions::BadDate, FSLib::Exceptions::BadTime, FSLib::Exceptions::BadTimeStamp); inline bool operator <( const TimeStamp &t ) const throw (FSLib::Exceptions::BadDate, FSLib::Exceptions::BadTime); inline bool operator <=( const TimeStamp &t ) const throw (FSLib::Exceptions::BadDate, FSLib::Exceptions::BadTime) { return *this < t || *this == t; } inline bool operator >( const TimeStamp &t ) const throw (FSLib::Exceptions::BadDate, FSLib::Exceptions::BadTime); inline bool operator >=( const TimeStamp &t ) const throw (FSLib::Exceptions::BadDate, FSLib::Exceptions::BadTime) { return *this > t || *this == t; } inline bool operator !=( const TimeStamp &t ) const throw (FSLib::Exceptions::BadDate, FSLib::Exceptions::BadTime); inline bool operator ==( const TimeStamp &t ) const throw (FSLib::Exceptions::BadDate, FSLib::Exceptions::BadTime); inline TimeStamp operator +( const TimePeriod & ) const; inline TimeStamp operator +( const DatePeriod & ) const; Time::t_seconds operator -( const TimeStamp &t ) const; inline TimeStamp operator -( const TimePeriod &t ) const; inline TimeStamp operator -( const DatePeriod & ) const; inline TimeStamp &operator +=( const TimePeriod & ); TimeStamp &operator +=( const DatePeriod & ); inline TimeStamp &operator -=( const TimePeriod & ); TimeStamp &operator -=( const DatePeriod & ); inline Day theDay() const; inline const Date &theDate() const throw (); inline const Time &theTime() const throw (); inline FSLib::wstring asString() const; inline FSLib::wstring asString( t_display ) const; TimeStamp &addSeconds( Time::t_seconds ); static TimeStamp now(); private: Date m_date; Time m_time; friend inline F3UTIL_DECLSPEC std::wostream &operator <<( std::wostream &, const TimeStamp & ); friend class Time; friend class Date; }; class F3UTIL_DECLSPEC TimePeriod { public: inline TimePeriod() throw (); inline TimePeriod( const TimePeriod &tp ) throw (); explicit inline TimePeriod( unsigned __int64 milliseconds ) throw (FSLib::Exceptions::BadTimePeriod); explicit inline TimePeriod( const FSLib::wstring & ) throw (FSLib::Exceptions::BadTimePeriod); inline TimePeriod( int hours, int minutes, Time::t_seconds seconds ); inline FSLib::wstring asString() const; inline int hours() const; inline int minutes() const; inline Time::t_seconds seconds() const; inline unsigned __int64 milliseconds() const; inline bool operator <( const TimePeriod &t ) const throw(); private: int m_hours, m_minutes; Time::t_seconds m_seconds; friend inline F3UTIL_DECLSPEC std::wostream &operator <<( std::wostream &, const TimePeriod & ); friend class TimeStamp; }; class F3UTIL_DECLSPEC DatePeriod { public: inline DatePeriod() throw (); inline DatePeriod( const DatePeriod &dp ) throw (); explicit inline DatePeriod( const FSLib::wstring & ) throw (FSLib::Exceptions::BadDatePeriod); inline DatePeriod( int years, int months, int days ); inline FSLib::wstring asString() const; inline bool operator <( const DatePeriod &t ) const throw (); inline bool operator <=( const DatePeriod &t ) const throw () { return *this < t || *this == t; } inline bool operator >( const DatePeriod &t ) const throw (); inline bool operator >=( const DatePeriod &t ) const throw () { return *this > t || *this == t; } inline bool operator !=( const DatePeriod &t ) const throw (); inline bool operator ==( const DatePeriod &t ) const throw () { return *this != t; } int years() const throw() { return m_years; } int months() const throw() { return m_months; } int days() const throw() { return m_days; } private: int m_years, m_months, m_days; friend inline F3UTIL_DECLSPEC std::wostream &operator <<( std::wostream &, const DatePeriod & ); friend class TimeStamp; friend class Date; }; class F3UTIL_DECLSPEC BlankPeriod { public: enum t_display { e_sql, e_user_short, e_user_long }; inline BlankPeriod(); inline ~BlankPeriod() throw (); inline bool inside( const TimeStamp &timeStamp ) const; inline FSLib::wstring asString() const; inline FSLib::wstring asString( t_display ) const; inline bool operator ==( const BlankPeriod & ) const; inline bool operator <( const BlankPeriod & ) const; inline const Nullable< TimeStamp > &start() const throw (); inline void start( const Nullable< TimeStamp > & ) throw (Exceptions::ReversedPeriod); inline const Nullable< TimeStamp > &end() const throw (); inline void end( const Nullable< TimeStamp > & ) throw (Exceptions::ReversedPeriod); protected: inline BlankPeriod( const Nullable< TimeStamp > &start, const Nullable< TimeStamp > &end ); inline BlankPeriod( const FSLib::wstring & ); inline Nullable< BlankPeriod > intersection( const BlankPeriod &bp ) const; private: Nullable< TimeStamp > m_start; Nullable< TimeStamp > m_end; inline void check() const throw (Exceptions::ReversedPeriod); }; inline F3UTIL_DECLSPEC std::wostream &operator <<( std::wostream &, const FSLib::BlankPeriod & ); template< typename T > class Period : public BlankPeriod { public: typedef T t_value; inline Period(); explicit inline Period( const t_value &value ); template< typename Y > explicit Period( const Period< Y > &p ) : BlankPeriod( p ), m_value( p.value() ) {} inline Period( const Period< void > &period, const t_value &value ); inline Period( const Nullable< TimeStamp > &start, const Nullable< TimeStamp > &end, const t_value &value ); inline Period( const FSLib::wstring &s, const t_value &value ); template< typename Y > Nullable< Period< T > > intersection( const Period< Y > &p ) const { Nullable< BlankPeriod > bpi( BlankPeriod::intersection( p ) ); if ( bpi.isnull() ) return Null; else return Period< T >( bpi.value().start(), bpi.value().end(), m_value ); } bool operator ==( const Period &p ) const { return BlankPeriod::operator ==( p ) && m_value == p.m_value; } bool operator <( const Period &p ) const { if ( BlankPeriod::operator ==( p ) ) return m_value < p.m_value; else return BlankPeriod::operator <( p ); } inline Period< void > period() const { return Period< void >( *this ); } inline const t_value &value() const; inline Nullable< t_value > value( const TimeStamp &timeStamp ) const; private: t_value m_value; }; template <> class Period< void > : public BlankPeriod { public: inline Period(); template< typename T > explicit Period( const Period< T > &p ) : BlankPeriod( p ) {} Period( const Period< void > &p ) : BlankPeriod( p ) {} inline Period( const Nullable< TimeStamp > &start, const Nullable< TimeStamp > &end ); inline Period( const FSLib::wstring &s ); template< typename T > Nullable< Period< void > > intersection( const Period< T > &p ) const { Nullable< BlankPeriod > bpi( BlankPeriod::intersection( p ) ); if ( bpi.isnull() ) return Null; else return Period< void >( bpi.value().start(), bpi.value().end() ); } }; /* Periods Support */ template< typename T, typename U = std::list< Period< T > > > class Periods { private: typedef Period< T > t_period; typedef U t_periods; public: inline Periods(); inline ~Periods() throw (); inline void insert( const T &t, const Period< void > &p ) { insert( Period< T >( p, t ) ); } inline void insert( const Period< T > & p ); inline Nullable< Period< T > > find( const TimeStamp &t ) const; inline FSLib::Period< T > &at( const TimeStamp & t ); inline const T operator []( const TimeStamp & t ) const; typedef typename t_periods::iterator iterator; typedef typename t_periods::const_iterator const_iterator; inline iterator begin(); inline const_iterator begin() const; inline iterator end(); inline const_iterator end() const; inline typename t_periods::size_type size() const { return m_periods.size(); } private: t_periods m_periods; }; namespace Exceptions { class F3UTIL_DECLSPEC BadDate : public Exception { public: inline BadDate(); inline BadDate( int y, int m, int d ); inline BadDate( const FSLib::wstring & ); protected: inline const wchar_t * const message() const throw (); }; class F3UTIL_DECLSPEC BadTime : public Exception { public: inline BadTime(); inline BadTime( int h, int m, Time::t_seconds s ); inline BadTime( const FSLib::wstring & ); protected: inline const wchar_t * const message() const throw (); }; class F3UTIL_DECLSPEC BadTimeStamp : public Exception { public: inline BadTimeStamp(); inline BadTimeStamp( int year, int month, int date, int h, int m, const Time::t_seconds &s ); inline BadTimeStamp( const FSLib::wstring & ); protected: inline const wchar_t * const message() const throw (); }; class F3UTIL_DECLSPEC BadDatePeriod : public Exception { public: BadDatePeriod( const DatePeriod &dp ); BadDatePeriod( int y, int m, int d ); BadDatePeriod( const FSLib::wstring & ); protected: inline const wchar_t * const message() const throw (); }; class F3UTIL_DECLSPEC BadTimePeriod : public Exception { public: BadTimePeriod( const TimePeriod &tp ); BadTimePeriod( int h, int m, const Time::t_seconds &s ); BadTimePeriod( const FSLib::wstring &formatted ); BadTimePeriod( const FSLib::wstring &error, unsigned __int64 ms ); protected: inline const wchar_t * const message() const throw (); }; class F3UTIL_DECLSPEC NoPeriod : public FSLib::Exceptions::Exception { public: inline NoPeriod( const TimeStamp & ); protected: inline const wchar_t * const message() const throw (); }; class F3UTIL_DECLSPEC ReversedPeriod : public FSLib::Exceptions::Exception { public: inline ReversedPeriod( const TimeStamp &, const TimeStamp & ); protected: inline const wchar_t * const message() const throw (); }; class F3UTIL_DECLSPEC OverlapPeriod : public FSLib::Exceptions::Exception { public: inline OverlapPeriod( const BlankPeriod &first, const BlankPeriod &second ); protected: inline const wchar_t * const message() const throw (); }; template< typename T > class OverlapPeriodT : public OverlapPeriod { public: inline OverlapPeriodT( const Period< T > &first, const Period< T > &second ); }; } } /* Period< typename T > */ template< typename T > inline FSLib::Period< T >::Period() : BlankPeriod() { } template< typename T > inline FSLib::Period< T >::Period( const t_value &v ) : BlankPeriod(), m_value( v ) { } template< typename T > inline FSLib::Period< T >::Period( const FSLib::Period< void > &p, const t_value &v ) : BlankPeriod( p.start(), p.end() ), m_value( v ) { } template< typename T > inline FSLib::Period< T >::Period( const FSLib::Nullable< TimeStamp > &s, const FSLib::Nullable< TimeStamp > &e, const t_value &v ) : BlankPeriod( s, e ), m_value( v ) { } template< typename T > inline FSLib::Period< T >::Period( const FSLib::wstring &s, const T &value ) : BlankPeriod( s ), m_value( value ) { } template< typename T > inline const typename FSLib::Period< T >::t_value &FSLib::Period< T >::value() const { return m_value; } template< typename T > inline FSLib::Nullable< typename FSLib::Period< T >::t_value > FSLib::Period< T >::value( const TimeStamp &t ) const { if ( inside( t ) ) { return m_value; } else { return Nullable< t_value >(); } } /* Period< void > */ inline FSLib::Period< void >::Period() : BlankPeriod() { } inline FSLib::Period< void >::Period( const FSLib::Nullable< FSLib::TimeStamp > &s, const FSLib::Nullable< FSLib::TimeStamp > &e ) : BlankPeriod( s, e ) { } inline FSLib::Period< void >::Period( const FSLib::wstring &s ) : BlankPeriod( s ) { } /* OverlapPeriodT< T > */ template< typename T > inline FSLib::Exceptions::OverlapPeriodT< T >::OverlapPeriodT( const Period< T > &first, const Period< T > &second ) : FSLib::Exceptions::OverlapPeriod( first, second ) { } /* Periods< T > */ template< typename T, typename U > inline FSLib::Periods< T, U >::Periods() : m_periods() { } template< typename T, typename U > inline FSLib::Periods< T, U >::~Periods() { while ( m_periods.begin() != m_periods.end() ) { try { m_periods.erase( m_periods.begin() ); } catch ( exception & ) { absorbException(); } } } template< typename T, typename U > inline void FSLib::Periods< T, U >::insert( const Period< T > & p ) { m_periods.push_back( p ); } template< typename T, typename U > inline FSLib::Nullable< FSLib::Period< T > > FSLib::Periods< T, U >::find( const TimeStamp &t ) const { Nullable< Period< T > > ret; for ( const_iterator i( m_periods.begin() ); i != m_periods.end(); ++i ) { if ( (*i).inside( t ) ) { if ( ret.isnull() ) { ret = (*i); } else { throw FSLib::Exceptions::OverlapPeriodT< T >( ret.value(), (*i) ); } } } return ret; } template< typename T, typename U > inline FSLib::Period< T > &FSLib::Periods< T, U >::at( const TimeStamp & t ) { Period< T > *ret = NULL; for ( iterator i( m_periods.begin() ); i != m_periods.end(); ++i ) { if ( (*i).inside( t ) ) { if ( ret == NULL ) { ret = &(*i); } else { throw FSLib::Exceptions::OverlapPeriodT< T >( *ret, (*i) ); } } } if ( ret == NULL ) throw FSLib::Exceptions::NoPeriod( t ); else return *ret; } template< typename T, typename U > inline const T FSLib::Periods< T, U >::operator []( const TimeStamp & t ) const { Nullable< Period< T > > ret( find( t ) ); if ( ret.isnull() ) { throw FSLib::Exceptions::NoPeriod( t ); } else { return ret.value().value(); } } template< typename T, typename U > inline typename FSLib::Periods< T, U >::iterator FSLib::Periods< T, U >::begin() { return m_periods.begin(); } template< typename T, typename U > inline typename FSLib::Periods< T, U >::const_iterator FSLib::Periods< T, U >::begin() const { return m_periods.begin(); } template< typename T, typename U > inline typename FSLib::Periods< T, U >::iterator FSLib::Periods< T, U >::end() { return m_periods.end(); } template< typename T, typename U > inline typename FSLib::Periods< T, U >::const_iterator FSLib::Periods< T, U >::end() const { return m_periods.end(); } #endif // FOST_TIMEDATE_HPP /* $History: FOST.timedate.hpp $ * * ***************** Version 26 ***************** * User: Kirit Date: 4/08/06 Time: 12:49 * Updated in $/FOST.3/F3Util * Corrected bug in TimeStamp::addSeconds() which was losing the * milliseconds. * * ***************** Version 25 ***************** * User: Kirit Date: 2/08/06 Time: 18:21 * Updated in $/FOST.3/F3Util * Make sure we cannot inadvertantly change a copy returned from operator * []. * * ***************** Version 24 ***************** * User: Kirit Date: 28/07/06 Time: 17:39 * Updated in $/FOST.3/F3Util * Extended Periods<> support. * * ***************** Version 23 ***************** * User: Kirit Date: 25/08/05 Time: 13:21 * Updated in $/FOST.3/F3Util * Added operator <() for FSLib::TimePeriod * * ***************** Version 22 ***************** * User: Kirit Date: 21/04/05 Time: 16:48 * Updated in $/FOST.3/f3util * Added some items to TimePeriod to help with the HTML interface. * * ***************** Version 21 ***************** * User: Kirit Date: 29/03/05 Time: 10:56 * Updated in $/FOST.3/F3Util * Debugged Period< void > copy constructor. * * ***************** Version 20 ***************** * User: Kirit Date: 26/03/05 Time: 13:34 * Updated in $/FOST.3/F3Util * * GUI now knows how to handle DatePeriod attributes. * * Moved userString to be part of HTML generation. * * ***************** Version 19 ***************** * User: Kirit Date: 25/03/05 Time: 11:22 * Updated in $/FOST.3/F3Util * Corrected Period<> comparison operator. * * ***************** Version 18 ***************** * User: Kirit Date: 10/06/04 Time: 18:35 * Updated in $/FOST.3/Include * Allowed a Period< T > to return a Period< void >. * * ***************** Version 17 ***************** * User: Kirit Date: 9/10/03 Time: 15:44 * Updated in $/FOST.3/INCLUDE * Headers re-arranged to give a proper SDK feel and to make determination * of required headers simpler. * * ***************** Version 16 ***************** * User: Kirit Date: 9/10/03 Time: 13:08 * Updated in $/FOST.3/F3Util * Check in ahead of change to FOST.timedate.hpp header. * * ***************** Version 14 ***************** * User: Kirit Date: 3/10/03 Time: 18:44 * Updated in $/FOST.3/F3Util * * ***************** Version 13 ***************** * User: Kirit Date: 20/07/03 Time: 22:23 * Updated in $/FOST/Cpp/FSCppUtil * Copy constructors (for braindead compiler error) and comparison * operators for DatePeriod. * * ***************** Version 12 ***************** * User: Kirit Date: 7/05/02 Time: 12:01 * Updated in $/FOST/Cpp/FSCppUtil * Wrapped std::basic_string<> in order to change the copy semantics to * stop the problems with using C++ in the COM layer for IIS. * * ***************** Version 11 ***************** * User: Kirit Date: 19/03/02 Time: 20:54 * Updated in $/FOST/Cpp/FSCppUtil * Corrected history from last check-in. * Updated TestAX.IDL to remove registry entries from removed classes. * * ***************** Version 10 ***************** * User: Kirit Date: 19/03/02 Time: 19:48 * Updated in $/FOST/Cpp/FSCppUtil * Debug compiles now all end in '_d'. * The C++ implementation names (Type.cppName) have been changed to also * include the DLL that the implementation is in as per the documentation. * In all source files the following have been done: * * Ensured that every header file has a revision object. * * Ensured that every translation unit has a revision object. * * Ensured that every source file (which understands comments) * has a history section. * * Changed all copyright notices to be for Obsideon Ltd. * * Changed copyright notices to use the longest possible timeframe. * * ***************** Version 9 ***************** * User: Kirit Date: 25/12/01 Time: 19:13 * Updated in $/FOST/Cpp/FSCppUtil * Some debugging of and extension of TimePeriod. * Added new reporting to Task and sorted out synchronised access to its * data members. * * ***************** Version 8 ***************** * User: Kirit Date: 24/12/01 Time: 15:21 * Updated in $/FOST/Cpp/FSCppUtil * Minor corrections to exceptions and some constructors. * * ***************** Version 7 ***************** * User: Kirit Date: 4/11/01 Time: 22:10 * Updated in $/FOST/Cpp/FSCppUtil * Switch to UTC time rather than local time. * * ***************** Version 6 ***************** * User: Kirit Date: 23/10/01 Time: 22:55 * Updated in $/FOST/FSCppUtil * Added new members to allow more complete arithmetic on TimeStamps. * * ***************** Version 5 ***************** * User: Kirit Date: 5/07/01 Time: 17:41 * Updated in $/FOST/FSCppUtil * First Unicode only version of FOST. * * ***************** Version 4 ***************** * User: Kirit Date: 2/07/01 Time: 14:19 * Updated in $/FOST/FSCppUtil * Addition of FSSettings DLL to handle simple default setting values. * * ***************** Version 3 ***************** * User: Kirit Date: 27/06/01 Time: 13:02 * Updated in $/FOST/FSCppUtil * Period<> templates now working and all basic database casts * operational. * * ***************** Version 2 ***************** * User: Kirit Date: 26/06/01 Time: 17:30 * Updated in $/FOST/FSCppUtil * Time & Date library working. * * ***************** Version 1 ***************** * User: Kirit Date: 26/06/01 Time: 16:44 * Created in $/FOST/FSCppUtil */