/* $Revision: 13 $ $Date: 28/07/06 17:39 $ Copyright © 1999-2005, FSL Technologies Limited. Contact "http://fost3.fsltech.com". */ #include "stdafx.h" #include using namespace std; using namespace FSLib; using namespace FSLib::Exceptions; namespace { Revision c_revision( L"$Archive: /FOST.3/F3Util/period.cpp $", __DATE__, L"$Revision: 13 $", L"$Date: 28/07/06 17:39 $" ); const wchar_t NoPeriodMsg[]=L"No Period was found that matched the time specified."; const wchar_t ReversedPeriodMsg[]=L"End timestamp is before start timestamp."; const wchar_t OverlapPeriodMsg[]=L"Two (or more) overlapping periods found in a Period<> container."; } /* Exceptions */ inline NoPeriod::NoPeriod( const TimeStamp &t ) : Exception() { m_info << L"Time to match to: " << t << endl; } inline const wchar_t * const NoPeriod::message() const { return NoPeriodMsg; } inline ReversedPeriod::ReversedPeriod( const TimeStamp & start, const TimeStamp & end ) : Exception() { m_info << L"Start time: " << start << endl << L"End time: " << end << endl; } inline const wchar_t * const ReversedPeriod::message() const { return ReversedPeriodMsg; } inline OverlapPeriod::OverlapPeriod( const BlankPeriod &f, const BlankPeriod &s ) : Exception() { m_info << L"Period: " << f.asString() << endl << L"Period: " << s.asString() << endl; } inline const wchar_t * const OverlapPeriod::message() const { return OverlapPeriodMsg; } /* BlankPeriod */ inline BlankPeriod::BlankPeriod() { check(); } inline BlankPeriod::BlankPeriod( const Nullable< TimeStamp > &s, const Nullable< TimeStamp > &e ) : m_start( s ), m_end( e ) { check(); } inline BlankPeriod::BlankPeriod( const FSLib::wstring &s ) { if ( s.substr( 0, 23 ) != FSLib::wstring( 23, L' ' ) ) { m_start = TimeStamp( s.substr( 0, 23 ) ); } if ( s.substr( 25 ) != FSLib::wstring( 23, L' ' ) && s.length() > 25 ) { m_end = TimeStamp( s.substr( 25 ) ); } check(); } inline BlankPeriod::~BlankPeriod() { } inline Nullable< BlankPeriod > BlankPeriod::intersection( const BlankPeriod &bp ) const { if ( bp.start().isnull() && bp.end().isnull() ) return *this; else if ( start().isnull() && end().isnull() ) return bp; Nullable< TimeStamp > s, e; if ( start().isnull() ) s = bp.start(); else if ( bp.start().isnull() ) s = start(); else if ( start().value() < bp.start().value() ) s = bp.start(); else s = start(); if ( end().isnull() ) e = bp.end(); else if ( bp.end().isnull() ) e = end(); else if ( end().value() > bp.end().value() ) e = bp.end(); else e = end(); if ( s.isnull() || e.isnull() || s.value() < e.value() ) return BlankPeriod( s, e ); else return Null; } inline void BlankPeriod::end( const Nullable< TimeStamp > &e ) { m_end = e; check(); } inline const Nullable< TimeStamp > &BlankPeriod::end() const { return m_end; } inline void BlankPeriod::start( const Nullable< TimeStamp > &s ) { m_start = s; check(); } inline void BlankPeriod::check() const { if ( !m_start.isnull() && !m_end.isnull() && ( m_end.value() < m_start.value() ) ) { throw ReversedPeriod( m_start.value(), m_end.value() ); } } inline const Nullable< TimeStamp > &BlankPeriod::start() const { return m_start; } inline bool BlankPeriod::inside( const FSLib::TimeStamp &t ) const { if ( m_start.isnull() && m_end.isnull() ) { return true; } else if ( m_start.isnull() && !m_end.isnull() && t < m_end.value() ) { return true; } else if ( !m_start.isnull() && m_end.isnull() && t >= m_start.value() ) { return true; } else if ( !m_start.isnull() && !m_end.isnull() && t >= m_start.value() && t < m_end.value() ) { return true; } else { return false; } } inline FSLib::wstring BlankPeriod::asString() const { return asString( e_sql ); } inline FSLib::wstring BlankPeriod::asString( t_display display ) const { if ( display == e_sql ) { return ( m_start.isnull() ? FSLib::wstring( 23, L' ' ) : m_start.value().asString() ) + L"->" + ( m_end.isnull() ? FSLib::wstring( 23, L' ' ) : m_end.value().asString() ); } else { if ( m_start.isnull() && m_end.isnull() ) { return L""; } else if ( m_start.isnull() ) { Date end = ( m_end.value() - DatePeriod( L"Y0000M000D0001" ) ).theDate(); return L"up until " + ( display == e_user_short ? end.asString( 3 ) : end.asString( 0 ) ); } else if ( m_end.isnull() ) { Date from = m_start.value().theDate(); return L"from " + ( display == e_user_short ? from.asString( 3 ) : from.asString( 0 ) ); } else if ( m_end.value().theDate() == m_start.value().theDate() ) { Date from = m_start.value().theDate(); return L"on " + ( display == e_user_short ? from.asString( 3 ) : from.asString( 0 ) ); } else { Date from = m_start.value().theDate(); Date end = ( m_end.value() - DatePeriod( L"Y0000M000D0001" ) ).theDate(); FSLib::wstring ret; // to prevent optimisation problem if ( from == end ) { ret = L"on " + ( display == e_user_short ? from.asString( 3 ) : from.asString( 0 ) ); } else { ret = L"between " + ( display == e_user_short ? from.asString( 3 ) : from.asString( 0 ) ) + L" and " + ( display == e_user_short ? end.asString( 3 ) : end.asString( 0 ) ); } return ret; } } } inline bool BlankPeriod::operator ==( const BlankPeriod &p ) const { return m_start == p.m_start && m_end == p.m_end; } inline bool BlankPeriod::operator <( const BlankPeriod &b ) const { if ( m_start.isnull() && b.m_start.isnull() ) { if ( m_end.isnull() && !b.m_end.isnull() ) { return false; } else if ( !m_end.isnull() && b.m_end.isnull() ) { return true; } else if ( !m_end.isnull() && !b.m_end.isnull() ) { return ( m_end.value() < b.m_end.value() ); } else { return false; } } else if ( !m_start.isnull() && b.m_start.isnull() ) { return false; } else if ( m_start.isnull() && !b.m_start.isnull() ) { return true; } else { return m_start.value() < b.m_start.value(); } } inline std::wostream &FSLib::operator <<( std::wostream &o, const FSLib::BlankPeriod &bp ) { return o << bp.asString(); } /* $History: period.cpp $ * * ***************** Version 13 ***************** * User: Kirit Date: 28/07/06 Time: 17:39 * Updated in $/FOST.3/F3Util * Extended Periods<> support. * * ***************** Version 12 ***************** * User: Kirit Date: 25/03/05 Time: 11:22 * Updated in $/FOST.3/F3Util * Corrected Period<> comparison operator. * * ***************** Version 11 ***************** * User: Kirit Date: 27/06/04 Time: 12:05 * Updated in $/FOST.3/F3Util * Debugged stream insertion operator for BlankPeriod. * * ***************** Version 10 ***************** * User: Kirit Date: 9/10/03 Time: 15:44 * Updated in $/FOST.3/F3Util * Headers re-arranged to give a proper SDK feel and to make determination * of required headers simpler. * * ***************** Version 8 ***************** * User: Kirit Date: 3/10/03 Time: 16:09 * Updated in $/FOST/Cpp/FSCppUtil * Added stdafx.h and stdafx.cpp pre-compiled header support. * * ***************** Version 7 ***************** * User: Kirit Date: 8/05/03 Time: 0:35 * Updated in $/FOST/Cpp/FSCppUtil * Added copy ctors to help compiler sort its life out. * * ***************** Version 6 ***************** * 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 5 ***************** * 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 4 ***************** * 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 3 ***************** * User: Kirit Date: 4/11/01 Time: 3:39 * Updated in $/FOST/Cpp/FSCppUtil * Updates to support Mutex lock testing. * Header revision information now captured. * Periods<> container updated to better support error reporting and fault * finding. * * ***************** Version 2 ***************** * User: Kirit Date: 5/07/01 Time: 17:41 * Updated in $/FOST/FSCppUtil * First Unicode only version of FOST. * * ***************** Version 1 ***************** * User: Kirit Date: 27/06/01 Time: 12:40 * Created in $/FOST/FSCppUtil */