Click here to Skip to main content
Click here to Skip to main content
Add your own
alternative version

XTimer - Timer and Stopwatch Utility with Source Code

, 20 Aug 2007 CPOL
XTimer provides countdown timer and stopwatch features in a compact MFC dialog app.
xtimer_demo.zip
src
alarm1.wav
app.manifest
hans.ico
hightime.inl
more.ico
play.ico
playd.bmp
playu.bmp
reset.ico
start.ico
stop.ico
vs2005
vs6
Release
XTimer.exe
XTimer.dsp
XTimer.dsw
wav files
4beeps.wav
alarm1.wav
alarm2.wav
alarmclock.wav
alert.wav
beeps.wav
bell.wav
buzzer.wav
chirp.wav
ding.wav
dingdong.wav
fanfare.wav
gong.wav
ohoh.wav
onebell.wav
quackquack.wav
ringer.wav
the_timer_has_expired_f.wav
the_timer_has_expired_m.wav
trumpet.wav
xtimer_sounds.zip
alarmclock.wav
alert.wav
buzzer.wav
divedive.wav
europolice.wav
quackquack.wav
siren.wav
//////////////////////////////////////////////////////////////////////
//
// HighTime.cpp: implementation of the CHighTime and the CHighTimeSpan classes.
//
//////////////////////////////////////////////////////////////////////
//
// CHighTime and CHighTimeSpan are two classes for high resolution time
// The range is +/-29000 years and smallest step is 0.1 microsecond
// They works like COleDateTime and COleDateTimeSpan.
// I wrote these because MS could not write working time classes
//
// Author: Hakan Trygg, h.kan@home.se
// Classes are not to be sold for profit.
// Please send me a mail if you find it useful and using it

// Revision history: 
// 1.0 : 12 Jan 2000 : /HT : Created
// 1.1 : 19 Jan 2000 : /HT : Made it possible to use classes without MFC
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "HighTime.h"

#pragma warning(disable : 4996)	// disable bogus deprecation warning

#define LLABS(i) (((i)<0)?-(i):(i))

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

#define MAX_TIME_BUFFER_SIZE 128

// Constant array with months # of days of year
int CHighTime::anMonthDayInYear[13] = {0, 31, 59, 90, 120, 151, 181, 
                                       212, 243, 273, 304, 334, 365};

// Static member for getting the current time
const CHighTime CHighTime::GetPresentTime()
{
    SYSTEMTIME systime;
    ::GetLocalTime(&systime);
    return CHighTime(systime);
} // CHighTime::GetPresentTime()

CHighTime::CHighTime(int nYear, int nMonth, int nDay,
                     int nHour, int nMinute, int nSecond, 
                     int nMilli , int nMicro ,int nNano)
                       // nMilli, nMicro & nNano default = 0
{
    _HighTimeFormat  SrcTime;
    SrcTime.nYear   = nYear;
    SrcTime.nMonth  = nMonth;
    SrcTime.nDay    = nDay;
    SrcTime.nHour   = nHour;
    SrcTime.nMinute = nMinute;
    SrcTime.nSecond = nSecond;
    SrcTime.nMilli  = nMilli;
    SrcTime.nMicro  = nMicro;
    SrcTime.nNano   = nNano;
    m_status = ConvertTimeToLongLong(SrcTime, m_liTime) ? valid : invalid;
} // CHighTime::CHighTime()

// CHighTime operators

#if defined(USE_MFC)
const CHighTime& CHighTime::operator=(const COleDateTime& dateSrc) 
{
    _HighTimeFormat  SrcTime;
    SrcTime.nYear   = dateSrc.GetYear();
    SrcTime.nMonth  = dateSrc.GetMonth();
    SrcTime.nDay    = dateSrc.GetDay();
    SrcTime.nHour   = dateSrc.GetHour();
    SrcTime.nMinute = dateSrc.GetMinute();
    SrcTime.nSecond = dateSrc.GetSecond();
    SrcTime.nMilli  = 0;
    SrcTime.nMicro  = 0;
    SrcTime.nNano  = 0;
    m_status = ConvertTimeToLongLong(SrcTime, m_liTime) ? valid : invalid;
    return *this;
} // CHighTime::operator=()

const CHighTime& CHighTime::operator=(const CTime& dateSrc) 
{
    _HighTimeFormat  SrcTime;
    SrcTime.nYear   = dateSrc.GetYear();
    SrcTime.nMonth  = dateSrc.GetMonth();
    SrcTime.nDay    = dateSrc.GetDay();
    SrcTime.nHour   = dateSrc.GetHour();
    SrcTime.nMinute = dateSrc.GetMinute();
    SrcTime.nSecond = dateSrc.GetSecond();
    SrcTime.nMilli  = 0;
    SrcTime.nMicro  = 0;
    SrcTime.nNano  = 0;
    m_status = ConvertTimeToLongLong(SrcTime, m_liTime) ? valid : invalid;
    return *this;
} // CHighTime::operator=()
#endif

const CHighTime& CHighTime::operator=(const SYSTEMTIME& systimeSrc)
{
    _HighTimeFormat  SrcTime;
    SrcTime.nYear   = systimeSrc.wYear;
    SrcTime.nMonth  = systimeSrc.wMonth;
    SrcTime.nDay    = systimeSrc.wDay;
    SrcTime.nHour   = systimeSrc.wHour;
    SrcTime.nMinute = systimeSrc.wMinute;
    SrcTime.nSecond = systimeSrc.wSecond;
    SrcTime.nMilli  = systimeSrc.wMilliseconds;
    SrcTime.nMicro  = 0;
    SrcTime.nNano  = 0;
    m_status = ConvertTimeToLongLong(SrcTime, m_liTime) ? valid : invalid;
    return *this;
} // CHighTime::operator=()

const CHighTime& CHighTime::operator=(const FILETIME& filetimeSrc)
{
    SYSTEMTIME systime;

    if (FileTimeToSystemTime(&filetimeSrc, &systime)) {
        _HighTimeFormat  SrcTime;
        SrcTime.nYear   = systime.wYear;
        SrcTime.nMonth  = systime.wMonth;
        SrcTime.nDay    = systime.wDay;
        SrcTime.nHour   = systime.wHour;
        SrcTime.nMinute = systime.wMinute;
        SrcTime.nSecond = systime.wSecond;
        SrcTime.nMilli  = systime.wMilliseconds;
        SrcTime.nMicro  = 0;
        SrcTime.nNano  = 0;
        m_status = ConvertTimeToLongLong(SrcTime, m_liTime) ? valid : invalid;
    }
    else {
        SetStatus(invalid);
    }
    return *this;
} // CHighTime::operator=()

#if _MFC_VER < 0x700
const CHighTime& CHighTime::operator=(const time_t& timeSrc)
{
    tm *pTimeSrc = localtime(&timeSrc);

    if (pTimeSrc) {
        _HighTimeFormat  SrcTime;
        SrcTime.nYear   = pTimeSrc->tm_year+1900;
        SrcTime.nMonth  = pTimeSrc->tm_mon+1;
        SrcTime.nDay    = pTimeSrc->tm_mday;
        SrcTime.nHour   = pTimeSrc->tm_hour;
        SrcTime.nMinute = pTimeSrc->tm_min;
        SrcTime.nSecond = pTimeSrc->tm_sec;
        SrcTime.nMilli  = 0;
        SrcTime.nMicro  = 0;
        SrcTime.nNano  = 0;
        m_status = ConvertTimeToLongLong(SrcTime, m_liTime) ? valid : invalid;
    }
    else {
		// Local time must have failed (timsSrc before 1/1/70 12am)
        SetStatus(invalid);
        ASSERT(FALSE);
    }
    return *this;
} // CHighTime::operator=(time_t)
#endif


int CHighTime::SetDateTime(int nYear, int nMonth, int nDay,
                           int nHour, int nMinute, int nSecond, 
                           int nMilli, int nMicro, int nNano)  
                            // nMilli, nMicro & nHundredsNano default = 0
{
    _HighTimeFormat  SrcTime;
    SrcTime.nYear   = nYear;
    SrcTime.nMonth  = nMonth;
    SrcTime.nDay    = nDay;
    SrcTime.nHour   = nHour;
    SrcTime.nMinute = nMinute;
    SrcTime.nSecond = nSecond;
    SrcTime.nMilli  = nMilli;
    SrcTime.nMicro  = nMicro;
    SrcTime.nNano   = nNano;
    return (m_status = ConvertTimeToLongLong(SrcTime, m_liTime) ? valid : invalid) == valid;
} // CHighTime::SetDateTime()

// HighTime helper function, static function
BOOL CHighTime::ConvertTimeToLongLong(const _HighTimeFormat  &SrcTime,
                                      LARGE_INTEGER &liDestTime)
{
	LARGE_INTEGER nDate;
    int iDays = SrcTime.nDay;
    UINT nHour = SrcTime.nHour;
    UINT nMinute = SrcTime.nMinute;
    UINT nSecond = SrcTime.nSecond;
    UINT nMilliSecond = SrcTime.nMilli;
    UINT nMicroSecond = SrcTime.nMicro;
    UINT nHundredsNano = (SrcTime.nNano +50) / 100;

    // Validate year and month
	if (SrcTime.nYear > 29000 || SrcTime.nYear < -29000 ||
        SrcTime.nMonth < 1 || SrcTime.nMonth > 12)
		return FALSE;

	//  Check for leap year
	BOOL bIsLeapYear = ((SrcTime.nYear & 3) == 0) &&
		                ((SrcTime.nYear % 100) != 0 || (SrcTime.nYear % 400) == 0);

    /*int nDaysInMonth = 
		anMonthDayInYear[SrcTime.nMonth] - anMonthDayInYear[SrcTime.nMonth-1] +
		((bIsLeapYear && SrcTime.nDay == 29 && SrcTime.nMonth == 2) ? 1 : 0);*/

    // Adjust time and frac time
    nMicroSecond += nHundredsNano / 10;
    nHundredsNano %= 10;
    nMilliSecond += nMicroSecond / 1000;
    nMicroSecond %= 1000;
    nSecond +=nMilliSecond / 1000;
    nMilliSecond %= 1000;
    nMinute += nSecond / 60;
    nSecond %= 60;
    nHour += nMinute / 60;
    nMinute %= 60;
    iDays += nHour / 24;
    nHour %= 24;

	//It is a valid date; make Jan 1, 1AD be 1
	nDate.QuadPart = SrcTime.nYear*365L + SrcTime.nYear/4 - SrcTime.nYear/100 + SrcTime.nYear/400 +
	                 anMonthDayInYear[SrcTime.nMonth-1] + iDays;

	//  If leap year and it's before March, subtract 1:
	if (SrcTime.nMonth <= 2 && bIsLeapYear)
		--nDate.QuadPart;

	//  Offset so that 01/01/1601 is 0
	nDate.QuadPart -= 584754L;

    // Change nDate to seconds
    nDate.QuadPart *= 86400L;
    nDate.QuadPart += (nHour * 3600L) + (nMinute * 60L) + nSecond;

    // Change nDate to hundreds of nanoseconds
    nDate.QuadPart *= 10000000L;
    nDate.QuadPart += (nMilliSecond * 10000L) + (nMicroSecond * 10L) + nHundredsNano;

	liDestTime = nDate;

    return TRUE;
} // CHighTime::ConvertTimeToLongLong()

BOOL CHighTime::ConvertLongLongToTime(const LARGE_INTEGER &liSrcTime,
                                       _HighTimeFormat  &DestTime)
{
    LARGE_INTEGER nTempTime;
	long nDaysAbsolute;     // Number of days since 1/1/0
	long nSecsInDay;        // Time in seconds since midnight
    long nMinutesInDay;     // Minutes in day

	long n400Years;         // Number of 400 year increments since 1/1/0
	long n400Century;       // Century within 400 year block (0,1,2 or 3)
	long n4Years;           // Number of 4 year increments since 1/1/0
	long n4Day;             // Day within 4 year block
							//  (0 is 1/1/yr1, 1460 is 12/31/yr4)
	long n4Yr;              // Year within 4 year block (0,1,2 or 3)
	BOOL bLeap4 = TRUE;     // TRUE if 4 year block includes leap year
    long nHNanosThisDay;
    long nMillisThisDay;

    nTempTime = liSrcTime;
	if (nTempTime.QuadPart < 0)		// fix by Mike Magatagan
		nTempTime.QuadPart *= -1; // abs()
    nHNanosThisDay      = (long)(nTempTime.QuadPart % 10000000L);
    nTempTime.QuadPart /= 10000000L;
    nSecsInDay          = (long)(nTempTime.QuadPart % 86400L);
    nTempTime.QuadPart /= 86400L;
    nDaysAbsolute       = (long)(nTempTime.QuadPart);
    nDaysAbsolute      += 584754L;	//  Add days from 1/1/0 to 01/01/1601

    // Calculate the day of week (sun=1, mon=2...)
    //   -1 because 1/1/0 is Sat.  +1 because we want 1-based
    DestTime.nDayOfWeek = (int)((nDaysAbsolute - 1) % 7L) + 1;


	// Leap years every 4 yrs except centuries not multiples of 400.
	n400Years = (long)(nDaysAbsolute / 146097L);

	// Set nDaysAbsolute to day within 400-year block
	nDaysAbsolute %= 146097L;

	// -1 because first century has extra day
	n400Century = (long)((nDaysAbsolute - 1) / 36524L);

	// Non-leap century
	if (n400Century != 0)
	{
		// Set nDaysAbsolute to day within century
		nDaysAbsolute = (nDaysAbsolute - 1) % 36524L;

		// +1 because 1st 4 year increment has 1460 days
		n4Years = (long)((nDaysAbsolute + 1) / 1461L);

		if (n4Years != 0)
			n4Day = (long)((nDaysAbsolute + 1) % 1461L);
		else
		{
			bLeap4 = FALSE;
			n4Day = (long)nDaysAbsolute;
		}
	}
	else
	{
		// Leap century - not special case!
		n4Years = (long)(nDaysAbsolute / 1461L);
		n4Day = (long)(nDaysAbsolute % 1461L);
	}

	if (bLeap4)
	{
		// -1 because first year has 366 days
		n4Yr = (n4Day - 1) / 365;

		if (n4Yr != 0)
			n4Day = (n4Day - 1) % 365;
	}
	else
	{
		n4Yr = n4Day / 365;
		n4Day %= 365;
	}

	// n4Day is now 0-based day of year. Save 1-based day of year, year number
	DestTime.nDayOfYear = (int)n4Day + 1;
	DestTime.nYear = n400Years * 400 + n400Century * 100 + n4Years * 4 + n4Yr;

	// Handle leap year: before, on, and after Feb. 29.
	if (n4Yr == 0 && bLeap4)
	{
		// Leap Year
		if (n4Day == 59)
		{
			/* Feb. 29 */
			DestTime.nMonth  = 2;
			DestTime.nDay = 29;
			goto DoTime;
		}

		// Pretend it's not a leap year for month/day comp.
		if (n4Day >= 60)
			--n4Day;
	}

	// Make n4DaY a 1-based day of non-leap year and compute
	//  month/day for everything but Feb. 29.
	++n4Day;

	// Month number always >= n/32, so save some loop time */
	for (DestTime.nMonth = (n4Day >> 5) + 1;
		n4Day > anMonthDayInYear[DestTime.nMonth]; DestTime.nMonth++);

	DestTime.nDay = (int)(n4Day - anMonthDayInYear[DestTime.nMonth-1]);

DoTime:
	if (nSecsInDay == 0)
		DestTime.nHour = DestTime.nMinute = DestTime.nSecond = 0;
	else
	{
		DestTime.nSecond = (UINT)nSecsInDay % 60L;
		nMinutesInDay = nSecsInDay / 60L;
		DestTime.nMinute = (UINT)nMinutesInDay % 60;
		DestTime.nHour   = (UINT)nMinutesInDay / 60;
	}

    if (nHNanosThisDay == 0)
		DestTime.nMilli = DestTime.nMicro = DestTime.nNano = 0;
	else
	{
		DestTime.nNano = (UINT)((nHNanosThisDay % 10L) * 100L);
		nMillisThisDay = nHNanosThisDay / 10L;
		DestTime.nMicro = (UINT)nMillisThisDay % 1000;
		DestTime.nMilli   = (UINT)nMillisThisDay / 1000;
	}

    return TRUE;
} // CHighTime::ConvertLongLongToTime()

void CHighTime::ConvertToStandardFormat(_HighTimeFormat &tmTempHigh, tm &tmSrc)
{
    // Convert internal tm to format expected by runtimes (sfrtime, etc)
	tmSrc.tm_year = tmTempHigh.nYear-1900;  // year is based on 1900
	tmSrc.tm_mon  = tmTempHigh.nMonth-1;      // month of year is 0-based
	tmSrc.tm_wday = tmTempHigh.nDayOfWeek-1;     // day of week is 0-based
	tmSrc.tm_yday = tmTempHigh.nDayOfYear-1;     // day of year is 0-based
    tmSrc.tm_mday = tmTempHigh.nDay;
    tmSrc.tm_hour = tmTempHigh.nHour;
    tmSrc.tm_min = tmTempHigh.nMinute;
    tmSrc.tm_sec = tmTempHigh.nSecond;
    tmSrc.tm_isdst = 0;
} // CHighTime::ConvertToStandardFormat()

int CHighTime::GetYear() const
{
	_HighTimeFormat tmTemp;
	if (GetStatus() == valid && ConvertLongLongToTime(m_liTime, tmTemp))
		return tmTemp.nYear;
	else
		return HIGH_DATETIME_ERROR;
} // CHighTime::GetYear()

int CHighTime::GetMonth() const       // month of year (1 = Jan)
{
	_HighTimeFormat tmTemp;
	if (GetStatus() == valid && ConvertLongLongToTime(m_liTime, tmTemp))
		return tmTemp.nMonth;
	else
		return HIGH_DATETIME_ERROR;
} // CHighTime::GetMonth()

int CHighTime::GetDay() const         // day of month (0-31)
{
	_HighTimeFormat tmTemp;
	if (GetStatus() == valid && ConvertLongLongToTime(m_liTime, tmTemp))
		return tmTemp.nDay;
	else
		return HIGH_DATETIME_ERROR;
} // CHighTime::GetDay()

int CHighTime::GetHour() const        // hour in day (0-23)
{
	_HighTimeFormat tmTemp;
	if (GetStatus() == valid && ConvertLongLongToTime(m_liTime, tmTemp))
		return tmTemp.nHour;
	else
		return HIGH_DATETIME_ERROR;
} // CHighTime::GetHour()

int CHighTime::GetMinute() const      // minute in hour (0-59)
{
	_HighTimeFormat tmTemp;
	if (GetStatus() == valid && ConvertLongLongToTime(m_liTime, tmTemp))
		return tmTemp.nMinute;
	else
		return HIGH_DATETIME_ERROR;

} // CHighTime::GetMinute()

int CHighTime::GetSecond() const      // second in minute (0-59)
{
	_HighTimeFormat tmTemp;
	if (GetStatus() == valid && ConvertLongLongToTime(m_liTime, tmTemp))
		return tmTemp.nSecond;
	else
		return HIGH_DATETIME_ERROR;
} // CHighTime::GetSecond()

int CHighTime::GetMilliSecond() const // millisecond in minute (0-999)
{
	_HighTimeFormat tmTemp;
	if (GetStatus() == valid && ConvertLongLongToTime(m_liTime, tmTemp))
		return tmTemp.nMilli;
	else
		return HIGH_DATETIME_ERROR;
} // CHighTime::GetMilliSecond()

int CHighTime::GetMicroSecond() const // microsecond in minute (0-999)
{
	_HighTimeFormat tmTemp;
	if (GetStatus() == valid && ConvertLongLongToTime(m_liTime, tmTemp))
		return tmTemp.nMicro;
	else
		return HIGH_DATETIME_ERROR;
} // CHighTime::GetMicroSecond()

int CHighTime::GetNanoSecond() const  // nanosecond in minute (0-999), step of 100ns
{
	_HighTimeFormat tmTemp;
	if (GetStatus() == valid && ConvertLongLongToTime(m_liTime, tmTemp))
		return tmTemp.nNano;
	else
		return HIGH_DATETIME_ERROR;
} // CHighTime::GetNanoSecond()

int CHighTime::GetDayOfWeek() const   // 1=Sun, 2=Mon, ..., 7=Sat
{
	_HighTimeFormat tmTemp;
	if (GetStatus() == valid && ConvertLongLongToTime(m_liTime, tmTemp))
		return tmTemp.nDayOfWeek;
	else
		return HIGH_DATETIME_ERROR;
} // CHighTime::GetDayOfWeek()

int CHighTime::GetDayOfYear() const   // days since start of year, Jan 1 = 1
{
	_HighTimeFormat tmTemp;
	if (GetStatus() == valid && ConvertLongLongToTime(m_liTime, tmTemp))
		return tmTemp.nDayOfYear;
	else
		return HIGH_DATETIME_ERROR;
} // CHighTime::GetDayOfYear()

BOOL CHighTime::GetAsSystemTime(SYSTEMTIME& sysTime) const
{
	BOOL bRetVal = FALSE;
	if (GetStatus() == valid)
	{
		_HighTimeFormat tmTemp;
		if (ConvertLongLongToTime(m_liTime, tmTemp))
		{
			sysTime.wYear = (WORD) tmTemp.nYear;
			sysTime.wMonth = (WORD) tmTemp.nMonth;
			sysTime.wDayOfWeek = (WORD) (tmTemp.nDayOfWeek - 1);
			sysTime.wDay = (WORD) tmTemp.nDay;
			sysTime.wHour = (WORD) tmTemp.nHour;
			sysTime.wMinute = (WORD) tmTemp.nMinute;
			sysTime.wSecond = (WORD) tmTemp.nSecond;
			sysTime.wMilliseconds = (WORD)tmTemp.nMilli;

			bRetVal = TRUE;
		}
	}

	return bRetVal;
} // CHighTime::GetAsSystemTime()

// CHighTime math
CHighTime CHighTime::operator+(const CHighTimeSpan &dateSpan) const
{
	CHighTime dateResult;    // Initializes m_status to valid

	// If either operand NULL, result NULL
	if (GetStatus() == null || dateSpan.GetStatus() == null)
	{
		dateResult.SetStatus(null);
		return dateResult;
	}

	// If either operand invalid, result invalid
	if (GetStatus() == invalid || dateSpan.GetStatus() == invalid)
	{
		dateResult.SetStatus(invalid);
		return dateResult;
	}

	// Compute the actual date difference by adding underlying dates
	dateResult.m_liTime.QuadPart = m_liTime.QuadPart + dateSpan.m_liSpan.QuadPart;

	// Validate within range
	//dateResult.CheckRange();

	return dateResult;
} // CHighTime::operator+()

CHighTime CHighTime::operator-(const CHighTimeSpan &dateSpan) const
{
	CHighTime dateResult;    // Initializes m_status to valid

	// If either operand NULL, result NULL
	if (GetStatus() == null || dateSpan.GetStatus() == null)
	{
		dateResult.SetStatus(null);
		return dateResult;
	}

	// If either operand invalid, result invalid
	if (GetStatus() == invalid || dateSpan.GetStatus() == invalid)
	{
		dateResult.SetStatus(invalid);
		return dateResult;
	}

	// Compute the actual date difference by adding underlying dates
	dateResult.m_liTime.QuadPart = m_liTime.QuadPart - dateSpan.m_liSpan.QuadPart;

	// Validate within range
	//dateResult.CheckRange();

	return dateResult;
} // CHighTime::operator-()


// CHighTimeSpan math
CHighTimeSpan CHighTime::operator-(const CHighTime& date) const
{
	CHighTimeSpan spanResult;

	// If either operand NULL, result NULL
	if (GetStatus() == null || date.GetStatus() == null)
	{
		spanResult.SetStatus(CHighTimeSpan::null);
		return spanResult;
	}

	// If either operand invalid, result invalid
	if (GetStatus() == invalid || date.GetStatus() == invalid)
	{
		spanResult.SetStatus(CHighTimeSpan::invalid);
		return spanResult;
	}

    spanResult.m_liSpan.QuadPart = m_liTime.QuadPart - date.m_liTime.QuadPart;


	return spanResult;
} // CHighTime::operator-()

// String helper functions
int CHighTime::FindStr(LPCTSTR pszSource, LPCTSTR pszSub, int nStart)
{
	int nLength = _tcslen(pszSource);
	if (nStart > nLength)
		return -1;

	// find first
	LPCTSTR pszSearch = _tcsstr(pszSource + nStart, pszSub);

	// return -1 for not found
	return (pszSearch == NULL) ? -1 : (int)(pszSearch - pszSource);
} // CHighTime::FindStr()

int CHighTime::ReplaceStr(LPTSTR pszDest, int nDestSize, LPCTSTR pszMask, LPCTSTR pszSource)
{
    int nCount, iInsertLen, iReplaceLen, iMoveLen, iDestLen;
    LPTSTR pSearch, pStartPos;

    nCount = 0;
    pStartPos = pszDest;
    while ( (pSearch = _tcsstr(pStartPos, pszMask)) != NULL) {
        pStartPos = pSearch + 1;
        ++nCount;
    }

    if (nCount > 0) {

        iReplaceLen = _tcslen(pszMask);
        iInsertLen = _tcslen(pszSource);

        // Can destination take the target?
        if ((int)_tcslen(pszDest) + nCount*(iInsertLen - iReplaceLen) > nDestSize) 
            return 0; // no => do nothing

        iDestLen = _tcslen(pszDest);
        pStartPos = pszDest;
        while ( (pSearch = _tcsstr(pStartPos, pszMask)) != NULL) {
           
            iMoveLen = iDestLen - (pSearch - pszDest);
            if (iReplaceLen != iInsertLen ) {

				// bug fix by Marcello
				if (iReplaceLen < iInsertLen ) {
					memmove(pSearch + (iInsertLen - iReplaceLen), pSearch, iMoveLen * sizeof(TCHAR));
				} else {
					memmove(pSearch, pSearch + (iReplaceLen - iInsertLen), 
						(iMoveLen - (iReplaceLen - iInsertLen)) * sizeof(TCHAR));
				}

                //memmove(pSearch + (iInsertLen - iReplaceLen), pSearch, iMoveLen * sizeof(TCHAR));

                iDestLen += iInsertLen - iReplaceLen;
                pszDest[iDestLen] = _T('\0');
            }
            memcpy(pSearch, pszSource, iInsertLen*sizeof(TCHAR));

            pStartPos = pSearch + 1;
        }
    }
    return nCount;
} // CHighTime::ReplaceStr()


// Formatting, Non MFC
LPCTSTR CHighTime::Format(LPTSTR pBuffer, int iBufferLen, LPCTSTR pFormat) const
{
	_HighTimeFormat tmHighTimeTemp;
    tm tmTemp;
    LPTSTR szTemp = NULL;
    int iPos;

	// If null, return empty string
	if (pBuffer == NULL || GetStatus() == null || iBufferLen <= 0)
		return NULL;

	// If invalid, return DateTime resource string
	if (GetStatus() == invalid || !ConvertLongLongToTime(m_liTime, tmHighTimeTemp))
	{
		_tcsncpy(pBuffer, INVALID_DATETIME, iBufferLen);
		return pBuffer;
	}

    if (iBufferLen <= 10)
        szTemp = new TCHAR[10];
    else
        szTemp = new TCHAR[iBufferLen+1];
    // Add milli, micro & nano part!!!!!!
    //%s for the millisecond part
    //%u for the microsecond part
    //%n for the nanosecond part
    _tcsncpy(pBuffer, pFormat, iBufferLen);

    iPos = FindStr(pBuffer, _T("%s"), 0);
    if (iPos >= 0) {
        wsprintf(szTemp,_T("%03d"),tmHighTimeTemp.nMilli);
        ReplaceStr(pBuffer, iBufferLen, _T("%s"), szTemp);
    }
    iPos = FindStr(pBuffer, _T("%#s"), 0);
    if (iPos >= 0) {
        wsprintf(szTemp,_T("%d"),tmHighTimeTemp.nMilli);
        ReplaceStr(pBuffer, iBufferLen, _T("%#s"), szTemp);
    }

    iPos = FindStr(pBuffer, _T("%u"), 0);
    if (iPos >= 0) {
        wsprintf(szTemp,_T("%03d"),tmHighTimeTemp.nMicro);
        ReplaceStr(pBuffer, iBufferLen, _T("%u"), szTemp);
    }
    iPos = FindStr(pBuffer, _T("%#u"), 0);
    if (iPos >= 0) {
        wsprintf(szTemp,_T("%d"),tmHighTimeTemp.nMicro);
        ReplaceStr(pBuffer, iBufferLen, _T("%#u"), szTemp);
    }

    iPos = FindStr(pBuffer, _T("%n"), 0);
    if (iPos >= 0) {
        wsprintf(szTemp,_T("%03d"),tmHighTimeTemp.nNano);
        ReplaceStr(pBuffer, iBufferLen, _T("%n"), szTemp);
    }
    iPos = FindStr(pBuffer, _T("%#n"), 0);
    if (iPos >= 0) {
        wsprintf(szTemp,_T("%d"),tmHighTimeTemp.nNano);
        ReplaceStr(pBuffer, iBufferLen, _T("%#n"), szTemp);
    }

	// Convert tm from internal format to standard format
    ConvertToStandardFormat(tmHighTimeTemp, tmTemp);

	// Fill in the buffer, disregard return value as it's not necessary
    _tcscpy(szTemp, pBuffer);
	_tcsftime(pBuffer, iBufferLen, szTemp, &tmTemp);

    delete [] szTemp;

	return pBuffer;
} // CHighTime::Format()

// formatting
#if defined(USE_MFC)
CString CHighTime::Format(LPCTSTR lpszFormat) const
{
    CString szParse(lpszFormat);
    CString szTemp,strDate;
	_HighTimeFormat tmHighTimeTemp;
    tm tmTemp;
    int iPos;

	// If null, return empty string
	if (GetStatus() == null)
		return strDate;

	// If invalid, return DateTime resource string
	if (GetStatus() == invalid || !ConvertLongLongToTime(m_liTime, tmHighTimeTemp))
	{
		VERIFY(strDate.LoadString(AFX_IDS_INVALID_DATETIME));
		return strDate;
	}

    // Add milli, micro & nano part!!!!!!
    //%s for the millisecond part
    //%u for the microsecond part
    //%n for the nanosecond part
    iPos = szParse.Find(_T("%s"), 0);
    if (iPos >= 0) {
        szTemp.Format(_T("%01d"),abs((int)tmHighTimeTemp.nMilli));	// hd+++
        szParse.Replace(_T("%s"),szTemp);
    }
    iPos = szParse.Find(_T("%#s"), 0);
    if (iPos >= 0) {
        szTemp.Format(_T("%d"),abs((int)tmHighTimeTemp.nMilli));
        szParse.Replace(_T("%#s"),szTemp);
    }
    iPos = szParse.Find(_T("%u"), 0);
    if (iPos >= 0) {
        szTemp.Format(_T("%03d"),abs((int)tmHighTimeTemp.nMicro));
        szParse.Replace(_T("%u"),szTemp);
    }
    iPos = szParse.Find(_T("%#u"), 0);
    if (iPos >= 0) {
        szTemp.Format(_T("%d"),abs((int)tmHighTimeTemp.nMicro));
        szParse.Replace(_T("%#u"),szTemp);
    }
    iPos = szParse.Find(_T("%n"), 0);
    if (iPos >= 0) {
        szTemp.Format(_T("%03d"),abs((int)tmHighTimeTemp.nNano));
        szParse.Replace(_T("%n"),szTemp);
    }
    iPos = szParse.Find(_T("%#n"), 0);
    if (iPos >= 0) {
        szTemp.Format(_T("%d"),abs((int)tmHighTimeTemp.nNano));
        szParse.Replace(_T("%#n"),szTemp);
    }

    // Convert tm from internal format to standard format
    ConvertToStandardFormat(tmHighTimeTemp, tmTemp);

	// Fill in the buffer, disregard return value as it's not necessary
	_tcsftime(strDate.GetBuffer(MAX_TIME_BUFFER_SIZE), MAX_TIME_BUFFER_SIZE, 
              szParse.GetBuffer(szParse.GetLength()), &tmTemp);
    szParse.ReleaseBuffer();
	strDate.ReleaseBuffer();

	return strDate;
} // CHighTime::Format()

CString CHighTime::Format(UINT nFormatID) const
{
	CString strFormat;
	VERIFY(strFormat.LoadString(nFormatID) != 0);
	return Format(strFormat);
} // CHighTime::Format()

// serialization
#ifdef _DEBUG
CDumpContext& AFXAPI operator<<(CDumpContext& dc, CHighTime dateSrc)
{
	dc << "\nCHighTime Object:";
	dc << "\n\tm_status = " << (long)dateSrc.m_status;
	dc << "\n\tdate = " << dateSrc.m_liTime.HighPart;
	return dc << "." << dateSrc.m_liTime.LowPart;
} //  operator<<(CDumpContext, CHighTime)
#endif // _DEBUG

CArchive& AFXAPI operator<<(CArchive& ar, CHighTime dateSrc)
{
	ar << (long)dateSrc.m_status;
	ar << dateSrc.m_liTime.HighPart;
	return ar << dateSrc.m_liTime.LowPart;
} // operator<<(CArchive, CHighTime)

CArchive& AFXAPI operator>>(CArchive& ar, CHighTime& dateSrc)
{
	ar >> (long&)dateSrc.m_status;
	ar >> dateSrc.m_liTime.HighPart;
	return ar >> dateSrc.m_liTime.LowPart;
} // operator>>(CArchive, CHighTime)
#endif // defined(USE_MFC)


// ******************************
// HighTimeSpan class
// ******************************
void CHighTimeSpan::SetHighTimeSpan(long lDays, int nHours, int nMinutes, int nSeconds,
                                    int nMillis, int nMicros, int nNanos)   
                                      // Milli, Micro & nano, default = 0
{

    int nHundredsNanos;
    
    if (nNanos >= 0)
        nHundredsNanos = (nNanos+50) / 100;
    else
        nHundredsNanos = (nNanos-50) / 100;

    nMicros += nHundredsNanos / 10;
    nHundredsNanos %= 10;
    nMillis += nMicros / 1000;
    nMicros %= 1000;
    nSeconds +=nMillis / 1000;
    nMillis %= 1000;
    nMinutes += nSeconds / 60;
    nSeconds %= 60;
    nHours += nMinutes / 60;
    nMinutes %= 60;
    lDays += nHours / 24;
    nHours %= 24;

    m_liSpan.QuadPart = lDays;
    m_liSpan.QuadPart *= 86400L;
    m_liSpan.QuadPart += (nHours * 3600L) +
                         (nMinutes * 60)  +
                         nSeconds;
    m_liSpan.QuadPart *= 10000000L;
    m_liSpan.QuadPart += (nMillis * 10000L) +
                         (nMicros * 10L) +
                         nHundredsNanos;

    SetStatus(valid);
} // CHighTimeSpan::SetHighTimeSpan()

LONGLONG CHighTimeSpan::GetTotalDays() const    // span in days (about -3.65e6 to 3.65e6)
{
    LONGLONG liTemp;
    liTemp = m_liSpan.QuadPart / 10000000L;
    liTemp /= 86400L;
    return liTemp;
} // CHighTimeSpan::GetTotalDays()

LONGLONG CHighTimeSpan::GetTotalHours() const   // span in hours (about -8.77e7 to 8.77e6)
{
    LONGLONG liTemp;
    liTemp = m_liSpan.QuadPart / 10000000L;
    liTemp /= 3600L;
    return liTemp;
} // CHighTimeSpan::GetTotalHours()

LONGLONG CHighTimeSpan::GetTotalMinutes() const // span in minutes (about -5.26e9 to 5.26e9)
{
    LONGLONG liTemp;
    liTemp = m_liSpan.QuadPart / 10000000L;
    liTemp /= 60L;
    return liTemp;
} // CHighTimeSpan::GetTotalMinutes()

LONGLONG CHighTimeSpan::GetTotalSeconds() const // span in seconds (about -3.16e11 to 3.16e11)
{
    LONGLONG liTemp;
    liTemp = m_liSpan.QuadPart / 10000000L;
    return liTemp;
} // CHighTimeSpan::GetTotalSeconds()

LONGLONG CHighTimeSpan::GetTotalMilliSeconds() const // span in milliseconds
{
    LONGLONG liTemp;
    liTemp = m_liSpan.QuadPart / 10000L;
    return liTemp;
} // CHighTimeSpan::GetTotalMilliSeconds()

LONGLONG CHighTimeSpan::GetTotalMicroSeconds() const // span in microseconds
{
    LONGLONG liTemp;
    liTemp = m_liSpan.QuadPart / 10L;
    return liTemp;
} // CHighTimeSpan::GetTotalMicroSeconds()

LONGLONG CHighTimeSpan::GetTotalNanoSeconds() const // span in nanoseconds
{
    LONGLONG liTemp;
    liTemp = m_liSpan.QuadPart * 100L;
    return liTemp;
} // CHighTimeSpan::GetTotalNanoSeconds()

int CHighTimeSpan::GetDays() const       // component days in span
{
    LONGLONG liTemp;
    liTemp = m_liSpan.QuadPart / 10000000L;
    liTemp = (liTemp / 86400L);
    return (int)liTemp;
} // CHighTimeSpan::GetDays()

int CHighTimeSpan::GetHours() const      // component hours in span (-23 to 23)
{
    LONGLONG liTemp;
    liTemp = m_liSpan.QuadPart / 10000000L;
    liTemp = (liTemp % 86400L) / 3600;
    return (int)liTemp;
} // CHighTimeSpan::GetHours()

int CHighTimeSpan::GetMinutes() const    // component minutes in span (-59 to 59)
{
    LONGLONG liTemp;
    liTemp = m_liSpan.QuadPart / 10000000L;
    liTemp = (liTemp % 3600L) / 60;
    return (int)liTemp;
} // CHighTimeSpan::GetMinutes()

int CHighTimeSpan::GetSeconds() const    // component seconds in span (-59 to 59)
{
    LONGLONG liTemp;
    liTemp = m_liSpan.QuadPart / 10000000L;
    liTemp = (liTemp % 60L);
    return (int)liTemp;
} // CHighTimeSpan::GetSeconds()

int CHighTimeSpan::GetMilliSeconds() const // component Milliseconds in span (-999 to 999)
{
    LONGLONG liTemp;
    liTemp = (m_liSpan.QuadPart % 10000000L) / 10000L;
    return (int)liTemp;
} // CHighTimeSpan::GetMilliSeconds()

int CHighTimeSpan::GetMicroSeconds() const // component Microseconds in span (-999 to 999)
{
    LONGLONG liTemp;
    liTemp = (m_liSpan.QuadPart % 10000L) / 10L;
    return (int)liTemp;
} // CHighTimeSpan::GetMicroSeconds()

int CHighTimeSpan::GetNanoSeconds() const  // component Nanoseconds in span (-900 to 900)
{
    LONGLONG liTemp;
    liTemp = (m_liSpan.QuadPart % 10) * 100L;
    return (int)liTemp;
} // CHighTimeSpan::GetNanoSeconds()


// CHighTimeSpan math
CHighTimeSpan CHighTimeSpan::operator+(const CHighTimeSpan& dateSpan) const
{
	CHighTimeSpan dateSpanTemp;

	// If either operand Null, result Null
	if (GetStatus() == null || dateSpan.GetStatus() == null)
	{
		dateSpanTemp.SetStatus(null);
		return dateSpanTemp;
	}

	// If either operand Invalid, result Invalid
	if (GetStatus() == invalid || dateSpan.GetStatus() == invalid)
	{
		dateSpanTemp.SetStatus(invalid);
		return dateSpanTemp;
	}

	// Add spans and validate within legal range
	dateSpanTemp.m_liSpan.QuadPart = m_liSpan.QuadPart + dateSpan.m_liSpan.QuadPart;

	return dateSpanTemp;
} // CHighTimeSpan::operator+()

CHighTimeSpan CHighTimeSpan::operator-(const CHighTimeSpan& dateSpan) const
{
	CHighTimeSpan dateSpanTemp;

	// If either operand Null, result Null
	if (GetStatus() == null || dateSpan.GetStatus() == null)
	{
		dateSpanTemp.SetStatus(null);
		return dateSpanTemp;
	}

	// If either operand Invalid, result Invalid
	if (GetStatus() == invalid || dateSpan.GetStatus() == invalid)
	{
		dateSpanTemp.SetStatus(invalid);
		return dateSpanTemp;
	}

	// Add spans and validate within legal range
	dateSpanTemp.m_liSpan.QuadPart = m_liSpan.QuadPart - dateSpan.m_liSpan.QuadPart;

	return dateSpanTemp;
} // CHighTimeSpan::operator-()

// formatting
LPTSTR CHighTimeSpan::Format(LPTSTR pBuffer, int iBufferLen, LPCTSTR pFormat) const
{
    CHighTime::_HighTimeFormat tmHighTimeTemp;
    tm tmTemp;
    int iPos;
    LPTSTR szTemp;

    // If null, return empty string
	if (pFormat == NULL || GetStatus() == null || iBufferLen <= 0)
		return NULL;

    // If invalid, return DateTimeSpan resource string
    if (GetStatus() == invalid || !CHighTime::ConvertLongLongToTime(m_liSpan, tmHighTimeTemp))
	{
		_tcsncpy(pBuffer, INVALID_DATETIME, iBufferLen);
		return pBuffer;
	}

    // Add milli, micro & nano part!!!!!!
    //%D for the Days part
    //%s for the millisecond part
    //%u for the microsecond part
    //%n for the nanosecond part
    if (iBufferLen <= 10)
        szTemp = new TCHAR[10];
    else
        szTemp = new TCHAR[iBufferLen+1];

    _tcsncpy(pBuffer, pFormat, iBufferLen);

    iPos = CHighTime::FindStr(pBuffer, _T("%D"), 0);
    if (iPos >= 0) {
        wsprintf(szTemp,_T("%0d"),LLABS(GetDays()));
        CHighTime::ReplaceStr(pBuffer, iBufferLen, _T("%D"), szTemp);
    }
    iPos = CHighTime::FindStr(pBuffer, _T("%#D"), 0);
    if (iPos >= 0) {
        wsprintf(szTemp,_T("%d"),LLABS(GetDays()));
        CHighTime::ReplaceStr(pBuffer, iBufferLen, _T("%#D"), szTemp);
    }

    iPos = CHighTime::FindStr(pBuffer, _T("%s"), 0);
    if (iPos >= 0) {
        wsprintf(szTemp,_T("%03d"),LLABS(GetMilliSeconds()));
        CHighTime::ReplaceStr(pBuffer, iBufferLen, _T("%s"), szTemp);
    }
    iPos = CHighTime::FindStr(pBuffer, _T("%#s"), 0);
    if (iPos >= 0) {
        wsprintf(szTemp,_T("%d"),LLABS(GetMilliSeconds()));
        CHighTime::ReplaceStr(pBuffer, iBufferLen, _T("%#s"), szTemp);
    }

    iPos = CHighTime::FindStr(pBuffer, _T("%u"), 0);
    if (iPos >= 0) {
        wsprintf(szTemp,_T("%03d"),LLABS(GetMicroSeconds()));
        CHighTime::ReplaceStr(pBuffer, iBufferLen, _T("%u"), szTemp);
    }
    iPos = CHighTime::FindStr(pBuffer, _T("%#u"), 0);
    if (iPos >= 0) {
        wsprintf(szTemp,_T("%d"),LLABS(GetMicroSeconds()));
        CHighTime::ReplaceStr(pBuffer, iBufferLen, _T("%#u"), szTemp);
    }

    iPos = CHighTime::FindStr(pBuffer, _T("%n"), 0);
    if (iPos >= 0) {
        wsprintf(szTemp,_T("%03d"),LLABS(GetNanoSeconds()));
        CHighTime::ReplaceStr(pBuffer, iBufferLen, _T("%n"), szTemp);
    }
    iPos = CHighTime::FindStr(pBuffer, _T("%#n"), 0);
    if (iPos >= 0) {
        wsprintf(szTemp,_T("%d"),LLABS(GetNanoSeconds()));
        CHighTime::ReplaceStr(pBuffer, iBufferLen, _T("%#n"), szTemp);
    }

	// Convert tm from internal format to standard format
	tmTemp.tm_year = tmHighTimeTemp.nYear-1601;   // year is based on 1900
	tmTemp.tm_mon  = tmHighTimeTemp.nMonth-1;     // month of year is 0-based
	tmTemp.tm_wday = tmHighTimeTemp.nDayOfWeek-1; // day of week is 0-based
	tmTemp.tm_yday = tmHighTimeTemp.nDayOfYear-1; // day of year is 0-based
    tmTemp.tm_mday = tmHighTimeTemp.nDay;
    tmTemp.tm_hour = tmHighTimeTemp.nHour;
    tmTemp.tm_min = tmHighTimeTemp.nMinute;
    tmTemp.tm_sec = tmHighTimeTemp.nSecond;
    tmTemp.tm_isdst = 0;

    // Fill in the buffer, disregard return value as it's not necessary
    _tcscpy(szTemp, pBuffer);
	_tcsftime(pBuffer, iBufferLen, szTemp, &tmTemp);
    delete [] szTemp;

    return pBuffer;
} // CHighTimeSpan::Format()

#if defined(USE_MFC)
CString CHighTimeSpan::Format(LPCTSTR pFormat) const
{
    CString szParse(pFormat);
    CString szTemp, strSpan;
    CHighTime::_HighTimeFormat tmHighTimeTemp;
    tm tmTemp;
    int iPos;

    // If null, return empty string
	if (pFormat == NULL || GetStatus() == null)
		return strSpan;

    // If invalid, return DateTimeSpan resource string
    if (GetStatus() == invalid || !CHighTime::ConvertLongLongToTime(m_liSpan, tmHighTimeTemp))
	{
		VERIFY(strSpan.LoadString(AFX_IDS_INVALID_DATETIMESPAN));
		return strSpan;
	}

    // Add milli, micro & nano part!!!!!!
    //%D for the Days part
    //%s for the millisecond part
    //%u for the microsecond part
    //%n for the nanosecond part
    iPos = szParse.Find(_T("%D"), 0);
    if (iPos >= 0) {
        szTemp.Format(_T("%0d"),LLABS(GetDays()));
        szParse.Replace(_T("%D"),szTemp);
    }
    iPos = szParse.Find(_T("%#D"), 0);
    if (iPos >= 0) {
        szTemp.Format(_T("%d"),LLABS(GetDays()));
        szParse.Replace(_T("%#D"),szTemp);
    }
    iPos = szParse.Find(_T("%s"), 0);
    if (iPos >= 0) {
        szTemp.Format(_T("%03d"),LLABS(GetMilliSeconds()));
        szParse.Replace(_T("%s"),szTemp);
    }
    iPos = szParse.Find(_T("%#s"), 0);
    if (iPos >= 0) {
        szTemp.Format(_T("%d"),LLABS(GetMilliSeconds()));
        szParse.Replace(_T("%#s"),szTemp);
    }
    iPos = szParse.Find(_T("%u"), 0);
    if (iPos >= 0) {
        szTemp.Format(_T("%03d"),LLABS(GetMicroSeconds()));
        szParse.Replace(_T("%u"),szTemp);
    }
    iPos = szParse.Find(_T("%#u"), 0);
    if (iPos >= 0) {
        szTemp.Format(_T("%d"),LLABS(GetMicroSeconds()));
        szParse.Replace(_T("%#u"),szTemp);
    }
    iPos = szParse.Find(_T("%n"), 0);
    if (iPos >= 0) {
        szTemp.Format(_T("%03d"),LLABS(GetNanoSeconds()));
        szParse.Replace(_T("%n"),szTemp);
    }
    iPos = szParse.Find(_T("%#n"), 0);
    if (iPos >= 0) {
        szTemp.Format(_T("%d"),LLABS(GetNanoSeconds()));
        szParse.Replace(_T("%#n"),szTemp);
    }

	// Convert tm from internal format to standard format
	tmTemp.tm_year = tmHighTimeTemp.nYear-1601;   // year is based on 1900
	tmTemp.tm_mon  = tmHighTimeTemp.nMonth-1;     // month of year is 0-based
	tmTemp.tm_wday = tmHighTimeTemp.nDayOfWeek-1; // day of week is 0-based
	tmTemp.tm_yday = tmHighTimeTemp.nDayOfYear-1; // day of year is 0-based
    tmTemp.tm_mday = tmHighTimeTemp.nDay;
    tmTemp.tm_hour = tmHighTimeTemp.nHour;
    tmTemp.tm_min = tmHighTimeTemp.nMinute;
    tmTemp.tm_sec = tmHighTimeTemp.nSecond;
    tmTemp.tm_isdst = 0;
    
    // Fill in the buffer, disregard return value as it's not necessary
	_tcsftime(strSpan.GetBuffer(MAX_TIME_BUFFER_SIZE), MAX_TIME_BUFFER_SIZE, 
              szParse.GetBuffer(szParse.GetLength()), &tmTemp);
    szParse.ReleaseBuffer();
	strSpan.ReleaseBuffer();

    return strSpan;
} // CHighTimeSpan::Format()

CString CHighTimeSpan::Format(UINT nID) const
{
    CString sBuffer;
    sBuffer.LoadString(nID);
    Format(sBuffer);
    return sBuffer;
} // CHighTimeSpan::Format()

// serialization
#ifdef _DEBUG
CDumpContext& AFXAPI operator<<(CDumpContext& dc, CHighTimeSpan dateSpanSrc)
{
	dc << "\nCHighTimeSpan Object:";
	dc << "\n\tm_status = " << (long)dateSpanSrc.m_status;
	dc << "\n\tdateSpan = " << dateSpanSrc.m_liSpan.HighPart;
	return dc << "." << dateSpanSrc.m_liSpan.LowPart;
} //  operator<<(CDumpContext, CHighTimeSpan)
#endif // _DEBUG

CArchive& AFXAPI operator<<(CArchive& ar, CHighTimeSpan dateSpanSrc)
{
	ar << (long)dateSpanSrc.m_status;
	ar << dateSpanSrc.m_liSpan.HighPart;
	return ar << dateSpanSrc.m_liSpan.LowPart;
} // operator<<(CArchive, CHighTimeSpan)

CArchive& AFXAPI operator>>(CArchive& ar, CHighTimeSpan& dateSpanSrc)
{
	ar >> (long&)dateSpanSrc.m_status;
	ar >> dateSpanSrc.m_liSpan.HighPart;
	return ar >> dateSpanSrc.m_liSpan.LowPart;
} // operator>>(CArchive, CHighTimeSpan)

#endif // defined(USE_MFC)

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Hans Dietrich
Software Developer (Senior) Hans Dietrich Software
United States United States
I attended St. Michael's College of the University of Toronto, with the intention of becoming a priest. A friend in the University's Computer Science Department got me interested in programming, and I have been hooked ever since.
 
Recently, I have moved to Los Angeles where I am doing consulting and development work.
 
For consulting and custom software development, please see www.hdsoft.org.






| Advertise | Privacy | Terms of Use | Mobile
Web04 | 2.8.141223.1 | Last Updated 20 Aug 2007
Article Copyright 2003 by Hans Dietrich
Everything else Copyright © CodeProject, 1999-2014
Layout: fixed | fluid