📄 cdate.cpp
字号:
///////////////////////////////////////////////////////////////////////////////
//
// BOOL CDateTime::GetDaysMonth(int nMonth, int nYear)
//
// Return the number of days in the month for the current year
//
BOOL CDateTime::GetDaysMonth(int nMonth, int nYear)
{
ASSERT(nMonth >= 1 && nMonth <= 12);
if (nMonth != 2)
{
return m_anMonthLen[nMonth];
} else if (IsLeapYear(nYear))
{
return 29;
} else
{
return 28;
}
};
///////////////////////////////////////////////////////////////////////////////
//
// CDateTime& CDateTime::operator+(int nDays)
//
// Addition/Subtraction operators
//
CDateTime CDateTime::operator+(int nDays)
{
long lDate = m_lDate;
DateAddDays(&lDate,nDays);
return CDateTime(lDate,m_lTime);
};
CDateTime CDateTime::operator-(int nDays)
{
long lDate = m_lDate;
DateAddDays(&lDate,-nDays);
return CDateTime(lDate,m_lTime);
};
///////////////////////////////////////////////////////////////////////////////
CDateTime CDateTime::operator+(double dDays)
{
double dTmp;
long lDate = m_lDate;
long lTime = m_lTime;
DateAddDays(&lDate,(long)dDays);
lTime += (long)(modf(dDays, &dTmp)*86400);
if (lTime < 0)
{
lTime += 86400;
DateAddDays(&lDate,-1);
}
else if (lTime >= 86400)
{
lTime -= 86400;
DateAddDays(&lDate,1);
};
return CDateTime(lDate,lTime);
};
///////////////////////////////////////////////////////////////////////////////
CDateTime CDateTime::operator-(double dValue)
{
return *this + (-dValue);
};
///////////////////////////////////////////////////////////////////////////////
//
// double CDateTime::operator-(CDateTime& rSrc)
//
// Determine number of whole and fractional parts between two dates
//
double CDateTime::operator-(CDateTime& rSrc)
{
// First convert dates to YYYYMMDD form
long lDate1 = rSrc.m_lDate;
long lDate2 = m_lDate;
if (lDate1 < 10000) lDate1 *= 100;
if (lDate1 < 1000000) lDate1 *= 100;
if (lDate2 < 10000) lDate2 *= 100;
if (lDate2 < 1000000) lDate2 *= 100;
// Nb. Not sure how DateDiff will cope with zero months and years
long lDays = DateDiff(lDate1, lDate2);
long lTime = m_lTime - rSrc.m_lTime;
if (lTime < 0)
{
lTime += 86400;
lDays--;
}
else if (lTime >= 86400)
{
lTime -= 86400;
lDays++;
};
return lDays + lTime/86400.0;
};
///////////////////////////////////////////////////////////////////////////////
//
// int CDateTime::MonthDisp(CDateTime)
//
// Returns the number of inclusive months between two dates
// E.G. MAR 93 to JAN 94 would be 11 months
//
int CDateTime::MonthDisp(CDateTime dateTo)
{
int nMonthDisp;
int nMonth = GetMonth();
int nYear = GetYear();
nMonthDisp = 0;
while (nYear < dateTo.GetYear())
{
nMonthDisp += 13 - nMonth;
nMonth = 1;
nYear++;
};
nMonthDisp += dateTo.GetMonth() - nMonth;
return nMonthDisp;
};
///////////////////////////////////////////////////////////////////////////////
//
// void CDateTime::AdvanceYear()
//
// Advances a date forward by one year
//
void CDateTime::AdvanceYear()
{
int nYear, nMonth, nDay;
LongAsDate(m_lDate,&nYear,&nMonth,&nDay);
DateAsLong(nYear+1,nMonth,nDay,&m_lDate);
};
void CDateTime::AdvanceMonth()
{
int nYear, nMonth, nDay;
LongAsDate(m_lDate,&nYear,&nMonth,&nDay);
nMonth++;
if (nMonth > 12)
{
nYear++;
nMonth = 1;
}
DateAsLong(nYear,nMonth,nDay,&m_lDate);
};
///////////////////////////////////////////////////////////////////////////////
//
// BOOL CDateTime::IsValid()
//
BOOL CDateTime::IsValid()
{
int nYear, nMonth, nDay, nHour, nMinute, nSecond;
return LongAsDate(m_lDate, &nYear, &nMonth, &nDay) &&
LongAsTime(m_lTime, &nHour, &nMinute, &nSecond);
};
///////////////////////////////////////////////////////////////////////////////
//
// void CDateTime::AsSystemDate()
//
// Sets the date and time to that of the current system time
//
void CDateTime::AsSystemDate()
{
time_t time_tDate; // Current system time and date
struct tm *pTmDate; // Current system time and date
time(&time_tDate);
pTmDate = localtime(&time_tDate);
*this = CDateTime(pTmDate->tm_year+1900, pTmDate->tm_mon+1, pTmDate->tm_mday,
pTmDate->tm_hour, pTmDate->tm_min, pTmDate->tm_sec);
}
///////////////////////////////////////////////////////////////////////////////
//
// BOOL CDateTime::IsDateValid(int nYear, int nMonth, int nDay)
//
// Nb. Zero day or zero month and day are allowed e.g. 1999 or Jun 1999
//
BOOL CDateTime::IsDateValid(int nYear, int nMonth, int nDay)
{
if (nYear < 100)
{
return FALSE;
}
if (nMonth == 0 && nDay == 0) return TRUE;
if( nMonth < 1 || nMonth > 12 )
{
return FALSE;
}
if (nDay == 0) return TRUE;
if( nDay < 1 || nDay > GetDaysMonth(nMonth,nYear) )
{
return FALSE;
} else
{
return TRUE;
}
};
///////////////////////////////////////////////////////////////////////////////
//
// BOOL IsTimeValid(int nHour, int nMinute, int nSecond)
//
BOOL CDateTime::IsTimeValid(int nHour, int nMinute, int nSecond)
{
BOOL bOK = TRUE;
// Validate
if (bOK)
{
if (!(nHour >= 0 && nHour < 24 &&
nMinute >= 0 && nMinute < 60 &&
nSecond >= 0 && nSecond < 60))
{
bOK = FALSE;
};
};
return bOK;
};
///////////////////////////////////////////////////////////////////////////////
//
// Dates are stored as YYYYMMDD or YYYYMM or YYYY
//
BOOL CDateTime::DateAsLong(int nYear, int nMonth, int nDay, long* plDate)
{
if (nDay == 0 && nMonth == 0) *plDate = nYear;
else if (nDay == 0) *plDate = nYear * 100 + nMonth;
else *plDate = nYear*10000 + nMonth*100 + nDay;
return TRUE;
}
///////////////////////////////////////////////////////////////////////////////
BOOL CDateTime::TimeAsLong(int nHour, int nMinute, int nSecond, long* plTime)
{
*plTime = nHour * 3600l + nMinute * 60l + nSecond;
return TRUE;
}
///////////////////////////////////////////////////////////////////////////////
BOOL CDateTime::LongAsDate(long lDate, int* pnYear, int* pnMonth, int* pnDay)
{
*pnYear = 0;
*pnMonth = 0;
*pnDay = 0;
if (lDate >= 10000000)
{
*pnYear = lDate/10000;
*pnMonth = (lDate - *pnYear*10000)/100;
*pnDay = (lDate - *pnYear*10000) - *pnMonth * 100;
}
else if (lDate >= 100000)
{
*pnYear = lDate/100;
*pnMonth = lDate - *pnYear*100;
}
else
{
*pnYear = lDate;
*pnMonth = 0;
*pnDay = 0;
}
return IsDateValid(*pnYear, *pnMonth, *pnDay);
}
///////////////////////////////////////////////////////////////////////////////
BOOL CDateTime::LongAsTime(long lTime, int* pnHour, int* pnMinute, int* pnSecond)
{
if (lTime == -1)
{
*pnHour = 0;
*pnMinute = 0;
*pnSecond = 0;
return TRUE;
}
*pnHour = (int)(lTime / 3600l);
*pnMinute = (int)((lTime - *pnHour*3600l)/60l);
*pnSecond = (int)((lTime - *pnHour*3600l) - *pnMinute * 60l);
return IsTimeValid(*pnHour, *pnMinute, *pnSecond);
}
///////////////////////////////////////////////////////////////////////////////
//
// BOOL CDateTime::StringAsTime()
//
// Converts a string to time, allowing for the water day
//
BOOL CDateTime::StringAsTime(CString sTime)
{
UINT nHour = 0;
UINT nMinute = 0;
UINT nSecond = 0;
BOOL bOK = TRUE;
// No time is indicated by -1
sTime.TrimLeft();
if (sTime.IsEmpty())
{
m_lTime = -1;
return TRUE;
}
// Extract values from the string
if (sscanf(sTime,"%d%*c%d%*c%d",&nHour, &nMinute, &nSecond) < 2)
{
bOK = FALSE;
}
// Construct the new datetime if the values are valid
if (bOK)
{
bOK = TimeAsLong(nHour,nMinute,nSecond,&m_lTime);
};
return bOK;
};
////////////////////////////////////////////////////////////////////////////////
//
// Adds lDays onto date plDate in format YYYYMMDD
//
BOOL CDateTime::DateAddDays(long* plDate, long lDays)
{
int nYear, nMonth, nDay;
BOOL bOK = TRUE;
if (LongAsDate(*plDate, &nYear, &nMonth, &nDay))
{
// Convert to a julian date
int nJul = GetJulDay(nYear, nMonth, nDay);
// Add year
int nYear2 = nYear + lDays/365;
// Add days
nJul += lDays%365;
nJul = nJul - LeapDays(nYear2-1) + LeapDays(nYear-1);
if (nJul > DaysInYear(nYear2))
{
nJul -= DaysInYear(nYear2++);
}
else if (nJul < 1)
{
nJul += DaysInYear(--nYear2);
}
// Convert back to a gregorian date
JulAsDate(nYear2, nJul, nMonth, nDay);
DateAsLong(nYear2, nMonth, nDay, plDate);
} else
{
bOK = FALSE;
}
return bOK;
}
////////////////////////////////////////////////////////////////////////////////
//
// Returns the difference between two dates in days (lDate2-lDate1)
//
// lDate1 and lDate2 are of the format YYYYMMDD
//
long CDateTime::DateDiff(long lDate1, long lDate2)
{
int nYear1, nMonth1, nDay1;
int nYear2, nMonth2, nDay2;
LongAsDate(lDate1, &nYear1, &nMonth1, &nDay1);
LongAsDate(lDate2, &nYear2, &nMonth2, &nDay2);
long lDays = (GetJulDay(nYear2, nMonth2, nDay2) + nYear2*365 + LeapDays(nYear2-1)) -
(GetJulDay(nYear1, nMonth1, nDay1) + nYear1*365 + LeapDays(nYear1-1));
return lDays;
}
///////////////////////////////////////////////////////////////////////////////
//
// Compares two dates, allowing for the fact that one may be a year only and
// the other may be a full date etc.
// Returns 0 if equal or -ve if first is earlier, positive if later
//
// For times, if either is set to null (-1) then assume they are equal
//
long CDateTime::DateCompare(long lDate0, long lDate1, long lTime0, long lTime1)
{
if (lDate0 > 1000000 && lDate1 < 1000000) lDate0 /= 100;
if (lDate0 < 1000000 && lDate1 > 1000000) lDate1 /= 100;
if (lDate0 > 10000 && lDate1 < 10000) lDate0 /= 100;
if (lDate0 < 10000 && lDate1 > 10000) lDate1 /= 100;
long lDiff = lDate0 - lDate1;
if (lDiff != 0) return lDiff;
// If comparing months or years then time is irrelevant
if (lDate0 < 1000000) return 0;
// Compare times
if (lTime0 == -1 || lTime1 == -1) return 0;
else return lTime0 - lTime1;
}
///////////////////////////////////////////////////////////////////////////////
BOOL CDateTime::operator==(CDateTime rdt)
{
ASSERT(IsValid() && rdt.IsValid());
return DateCompare(m_lDate, rdt.m_lDate, m_lTime, rdt.m_lTime) == 0;
}
BOOL CDateTime::operator!=(CDateTime rdt)
{
ASSERT(IsValid() && rdt.IsValid());
return DateCompare(m_lDate, rdt.m_lDate, m_lTime, rdt.m_lTime) != 0;
}
BOOL CDateTime::operator<(CDateTime rdt)
{
ASSERT(IsValid() && rdt.IsValid());
return DateCompare(m_lDate, rdt.m_lDate, m_lTime, rdt.m_lTime) < 0;
}
BOOL CDateTime::operator>(CDateTime rdt)
{
ASSERT(IsValid() && rdt.IsValid());
return DateCompare(m_lDate, rdt.m_lDate, m_lTime, rdt.m_lTime) > 0;
}
BOOL CDateTime::operator>=(CDateTime rdt)
{
ASSERT(IsValid() && rdt.IsValid());
return DateCompare(m_lDate, rdt.m_lDate, m_lTime, rdt.m_lTime) >= 0;
}
BOOL CDateTime::operator<=(CDateTime rdt)
{
ASSERT(IsValid() && rdt.IsValid());
return DateCompare(m_lDate, rdt.m_lDate, m_lTime, rdt.m_lTime) <= 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -