summaryrefslogtreecommitdiff
path: root/src/core/xbdate.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/xbdate.cpp')
-rwxr-xr-xsrc/core/xbdate.cpp341
1 files changed, 203 insertions, 138 deletions
diff --git a/src/core/xbdate.cpp b/src/core/xbdate.cpp
index ba0fdf1..54834ac 100755
--- a/src/core/xbdate.cpp
+++ b/src/core/xbdate.cpp
@@ -2,7 +2,7 @@
XBase64 Software Library
-Copyright (c) 1997,2003,2014,2022 Gary A Kunkel
+Copyright (c) 1997,2003,2014,2022,2023 Gary A Kunkel
The xb64 software library is covered under the terms of the GPL Version 3, 2007 license.
@@ -25,22 +25,36 @@ int xbDate::iAggregatedDaysInMonths[2][13];
//! @brief Constructor.
xbDate::xbDate() {
- Sysdate();
+ sDate8.Set( "" );
SetDateTables();
}
/*************************************************************************/
//! @brief Constructor.
/*!
+ \param iInitOpt - Constructor to use to initialize date static variables
+ Called by the main xbXbase::xbXBase constructor
+*/
+
+xbDate::xbDate( xbUInt16 ) {
+
+ SetDateTables();
+ Sysdate();
+}
+/*************************************************************************/
+//! @brief Constructor.
+/*!
\param sDate8In - Input date.
*/
xbDate::xbDate( const xbString & sDate8In ) {
+
if( DateIsValid( sDate8In ))
sDate8.Set( sDate8In );
else
- Sysdate();
- SetDateTables();
+ sDate8.Set( "" );
+
+ // SetDateTables();
}
/*************************************************************************/
@@ -53,8 +67,9 @@ xbDate::xbDate( const char * sDate8In ) {
if( DateIsValid( sDate8In ))
sDate8.Set( sDate8In );
else
- Sysdate();
- SetDateTables();
+ sDate8.Set( "" );
+
+ // SetDateTables();
}
/*************************************************************************/
@@ -63,7 +78,7 @@ xbDate::xbDate( const char * sDate8In ) {
\param lJulDate - Input julian date.
*/
xbDate::xbDate( xbInt32 lJulDate ) {
- SetDateTables();
+ // SetDateTables();
JulToDate8( lJulDate );
}
@@ -81,68 +96,76 @@ void xbDate::operator=( const xbDate & dt ){
/*************************************************************************/
//! @brief operator +=
/*!
- This routine adds lDays to the date
+ This routine adds lDays to the date if the date is not null.
\param lDays - Number of days to add to the date.
*/
void xbDate::operator+=( xbInt32 lDays ){
- JulToDate8( JulianDays() + lDays );
+ if( !IsNull() )
+ JulToDate8( JulianDays() + lDays );
}
/*************************************************************************/
//! @brief operator -=
/*!
- This routine subtracts lDays from the date.
+ This routine subtracts lDays from the date if the date is not null.
\param lDays - Number of days to subtract from the date.
*/
void xbDate::operator-=( xbInt32 lDays ){
- JulToDate8( JulianDays() - lDays );
+ if( !IsNull() )
+ JulToDate8( JulianDays() - lDays );
}
/*************************************************************************/
//! @brief operator ++
/*!
- This routine adds one day to the date field.
+ This routine adds one day to the date field if the date is not null.
*/
void xbDate::operator++(xbInt32){
- *this+=1;
+ if( !IsNull() )
+ *this+=1;
}
/*************************************************************************/
//! @brief operator --
/*!
- This routine subtracts one day from the date field.
+ This routine subtracts one day from the date field if the date is not null.
*/
void xbDate::operator--(xbInt32){
- *this-=1;
- return;
+ if( !IsNull())
+ *this-=1;
}
/*************************************************************************/
//! @brief operator -
/*!
This routine subtracts one date from another date returning the difference.
- \param dt - Date to subtract.
- \returns Number of days
+ \param dt - Date to subtract
+ \returns Number of days difference or zero if one of the dates is null.
*/
xbInt32 xbDate::operator-( const xbDate &dt ) const{
- return JulianDays() - dt.JulianDays();
+ if( !IsNull() && !dt.IsNull() )
+ return JulianDays() - dt.JulianDays();
+ else
+ return 0;
}
/*************************************************************************/
//! @brief operator +
/*!
- This routine adds additional days to a date field.
+ This routine adds additional days to a valid date field.
\param lCount - Number of days to add.
\returns New date in CCYYMMDD format.
*/
const char *xbDate::operator+( xbInt32 lCount ){
- JulToDate8( JulianDays() + lCount );
+ if( !IsNull() )
+ JulToDate8( JulianDays() + lCount );
return sDate8.Str();
}
/*************************************************************************/
//! @brief operator -
/*!
- This routine subtracts days from a date field.
+ This routine subtracts days from a valid date field.
\param lCount - Number of days to subtract.
\returns New date in CCYYMMDD format.
*/
const char *xbDate::operator-( xbInt32 lCount ){
- JulToDate8( JulianDays() - lCount );
+ if( !IsNull() )
+ JulToDate8( JulianDays() - lCount );
return sDate8;
}
/*************************************************************************/
@@ -232,13 +255,14 @@ xbBool xbDate::operator>=( const xbDate &dt ) const {
/*!
This routine calculates a century for a given year. It uses an 80/20
rolling date window to calculate the century.
-
+
\param iCalcYear - Two digit year to calculate a century for.
\returns Century calculated for the two digit year.
*/
xbInt16 xbDate::CalcRollingCenturyForYear( xbInt16 iCalcYear ) const {
xbDate d;
+ d.Sysdate();
xbInt16 iThisYear = d.YearOf();
xbInt16 iThisCentury = d.CenturyOf();
iThisYear -= (iThisCentury * 100);
@@ -254,14 +278,18 @@ xbInt16 xbDate::CalcRollingCenturyForYear( xbInt16 iCalcYear ) const {
/*************************************************************************/
//! @brief Get century for date.
/*!
- \returns This routine returns the century from the date.
+ \returns the century from the valid date.\ or 0 for a null date.
*/
xbInt16 xbDate::CenturyOf() const {
- char Century[3];
- Century[0] = sDate8[1];
- Century[1] = sDate8[2];
- Century[2] = 0x00;
- return( atoi( Century ));
+ if( !IsNull() ){
+ char Century[3];
+ Century[0] = sDate8[1];
+ Century[1] = sDate8[2];
+ Century[2] = 0x00;
+ return( atoi( Century ));
+ } else {
+ return 0;
+ }
}
/*************************************************************************/
//! @brief Get the day of the week.
@@ -271,22 +299,24 @@ xbInt16 xbDate::CenturyOf() const {
*/
xbInt16 xbDate::CharDayOf( xbString &sOutCharDay ) {
- struct tm tblock;
- char buf[25];
-
- tblock.tm_year = YearOf() - 1900;
- tblock.tm_mon = MonthOf() - 1;
- tblock.tm_mday = DayOf( XB_FMT_MONTH );
- tblock.tm_hour = 0;
- tblock.tm_min = 0;
- tblock.tm_sec = 1;
- tblock.tm_isdst = -1;
- if( mktime( &tblock ) == -1 ){
- sOutCharDay = "" ;
- return XB_INVALID_DATE;
- } else {
- strftime( buf, 25, "%A", &tblock );
- sOutCharDay = buf;
+ if( !IsNull()){
+ struct tm tblock;
+ char buf[25];
+
+ tblock.tm_year = YearOf() - 1900;
+ tblock.tm_mon = MonthOf() - 1;
+ tblock.tm_mday = DayOf( XB_FMT_MONTH );
+ tblock.tm_hour = 0;
+ tblock.tm_min = 0;
+ tblock.tm_sec = 1;
+ tblock.tm_isdst = -1;
+ if( mktime( &tblock ) == -1 ){
+ sOutCharDay = "" ;
+ return XB_INVALID_DATE;
+ } else {
+ strftime( buf, 25, "%A", &tblock );
+ sOutCharDay = buf;
+ }
}
return XB_NO_ERROR;;
}
@@ -297,21 +327,24 @@ xbInt16 xbDate::CharDayOf( xbString &sOutCharDay ) {
\returns XB_INVALID_DATE<br>XB_NO_ERROR
*/
xbInt16 xbDate::CharMonthOf( xbString &sOutCharMonth ) {
- struct tm tblock;
- char buf[25];
- tblock.tm_year = YearOf() - 1900;
- tblock.tm_mon = MonthOf() - 1;
- tblock.tm_mday = DayOf( XB_FMT_MONTH );
- tblock.tm_hour = 0;
- tblock.tm_min = 0;
- tblock.tm_sec = 1;
- tblock.tm_isdst = -1;
- if( mktime( &tblock ) == -1 ){
- sOutCharMonth = "";
- return XB_INVALID_DATE;
- } else {
- strftime( buf, 25, "%B", &tblock );
- sOutCharMonth = buf;
+
+ if( !IsNull()){
+ struct tm tblock;
+ char buf[25];
+ tblock.tm_year = YearOf() - 1900;
+ tblock.tm_mon = MonthOf() - 1;
+ tblock.tm_mday = DayOf( XB_FMT_MONTH );
+ tblock.tm_hour = 0;
+ tblock.tm_min = 0;
+ tblock.tm_sec = 1;
+ tblock.tm_isdst = -1;
+ if( mktime( &tblock ) == -1 ){
+ sOutCharMonth = "";
+ return XB_INVALID_DATE;
+ } else {
+ strftime( buf, 25, "%B", &tblock );
+ sOutCharMonth = buf;
+ }
}
return XB_NO_ERROR;
}
@@ -387,45 +420,48 @@ xbBool xbDate::DateIsValid( const xbString &sDateIn ) const {
xbInt16 xbDate::DayOf( xbInt16 iFormat ) const {
- xbInt16 iOutDay = 0;
- char sDay[3];
- xbInt16 iDay, iMonth, iYear, iDay2;
-
- // check for valid format switch
- if( iFormat!=XB_FMT_WEEK && iFormat!=XB_FMT_MONTH && iFormat!=XB_FMT_YEAR )
- return XB_INVALID_OPTION;
-
- if( iFormat == XB_FMT_WEEK ){
- //DayOf( XB_FMT_MONTH, iDay );
- iDay = DayOf( XB_FMT_MONTH );
- iMonth = MonthOf();
- iYear = YearOf();
-
- // The following formula uses Zeller's Congruence to determine the day of the week
- if( iMonth > 2 ) // init to February
- iMonth -= 2;
- else {
- iMonth += 10;
- iYear--;
- }
- iDay2 = ((13 * iMonth - 1) / 5) + iDay + ( iYear % 100 ) +
- (( iYear % 100 ) / 4) + ((iYear /100 ) / 4 ) - 2 *
- ( iYear / 100 ) + 77 ;
+ if( !IsNull()){
+ xbInt16 iOutDay = 0;
+ char sDay[3];
+ xbInt16 iDay, iMonth, iYear, iDay2;
+
+ // check for valid format switch
+ if( iFormat!=XB_FMT_WEEK && iFormat!=XB_FMT_MONTH && iFormat!=XB_FMT_YEAR )
+ return XB_INVALID_OPTION;
+
+ if( iFormat == XB_FMT_WEEK ){
+ //DayOf( XB_FMT_MONTH, iDay );
+ iDay = DayOf( XB_FMT_MONTH );
+ iMonth = MonthOf();
+ iYear = YearOf();
+
+ // The following formula uses Zeller's Congruence to determine the day of the week
+ if( iMonth > 2 ) // init to February
+ iMonth -= 2;
+ else {
+ iMonth += 10;
+ iYear--;
+ }
+ iDay2 = ((13 * iMonth - 1) / 5) + iDay + ( iYear % 100 ) +
+ (( iYear % 100 ) / 4) + ((iYear /100 ) / 4 ) - 2 *
+ ( iYear / 100 ) + 77 ;
- iOutDay = iDay2 - 7 * ( iDay2 / 7 );
- iOutDay == 6 ? iOutDay = 0 : iOutDay++;
- }
- else if( iFormat == XB_FMT_MONTH ){
- sDay[0] = sDate8[7];
- sDay[1] = sDate8[8];
- sDay[2] = 0x00;
- iOutDay = atoi( sDay );
+ iOutDay = iDay2 - 7 * ( iDay2 / 7 );
+ iOutDay == 6 ? iOutDay = 0 : iOutDay++;
+ }
+ else if( iFormat == XB_FMT_MONTH ){
+ sDay[0] = sDate8[7];
+ sDay[1] = sDate8[8];
+ sDay[2] = 0x00;
+ iOutDay = atoi( sDay );
+ } else {
+ iOutDay = iAggregatedDaysInMonths[IsLeapYear()][MonthOf()-1] + DayOf( XB_FMT_MONTH );
+ }
+ return iOutDay;
} else {
- iOutDay = iAggregatedDaysInMonths[IsLeapYear()][MonthOf()-1] + DayOf( XB_FMT_MONTH );
+ return 0;
}
- return iOutDay;
}
-
/*************************************************************************/
#ifdef XB_DEBUG_SUPPORT
//! @brief Dump date information to stdout.
@@ -466,7 +502,6 @@ void xbDate::DumpDateTables(){
*/
xbInt16 xbDate::CTOD( const xbString &sCtodInDate ){
-
if( sCtodInDate[1] != ' ' && ( sCtodInDate[3] == '\\' || sCtodInDate[3] == '/') ){
char yy[3];
yy[0] = sCtodInDate[7];
@@ -518,6 +553,9 @@ xbInt16 xbDate::FormatDate( const xbString &sFmtIn, xbString &sOutFmtDate ){
xbString sWrkFmt;
sOutFmtDate = "";
+ if( IsNull())
+ return XB_NO_ERROR;
+
/* use format for this specific string if available, else use default format */
if( strlen( sFmtIn ) > 0 )
sWrkFmt = sFmtIn;
@@ -600,6 +638,8 @@ const char * xbDate::Str() const{
\returns xbTrue - Is leapyear.<br> xbFalse - Not a leap year.
*/
xbBool xbDate::IsLeapYear() const {
+ if( IsNull() )
+ return xbFalse;
xbInt16 iYear = YearOf();
if(( iYear % 4 == 0 && iYear % 100 != 0 ) || iYear % 400 == 0 )
return xbTrue;
@@ -619,15 +659,30 @@ xbBool xbDate::IsLeapYear( xbInt16 iYear ) const {
return xbFalse;
}
/*************************************************************************/
+//! @brief Determine if date is null date
+/*!
+ \returns xbTrue - If null date.<br> xbFalse - Not a null date.
+*/
+xbBool xbDate::IsNull() const {
+ if( sDate8.Len() < 8 )
+ return xbTrue;
+ else
+ return xbFalse;
+}
+/*************************************************************************/
//! @brief Calculate julian days for a given date.
/*!
\returns The number of days since 01/01/0001 + JUL_OFFSET.
*/
xbInt32 xbDate::JulianDays() const{
- xbInt32 ly = YearOf() - 1;
- xbInt32 lDays = ly * 365L + ly / 4L - ly / 100L + ly / 400L;
- lDays += DayOf( XB_FMT_YEAR );
- return lDays + JUL_OFFSET;
+ if( !IsNull()){
+ xbInt32 ly = YearOf() - 1;
+ xbInt32 lDays = ly * 365L + ly / 4L - ly / 100L + ly / 400L;
+ lDays += DayOf( XB_FMT_YEAR );
+ return lDays + JUL_OFFSET;
+ } else {
+ return 0;
+ }
}
/*************************************************************************/
//! @brief Convert the number of julian days to gregorian date.
@@ -637,24 +692,23 @@ xbInt32 xbDate::JulianDays() const{
*/
xbInt16 xbDate::JulToDate8( xbInt32 lJulDays )
{
- lJulDays -= JUL_OFFSET;
- // calculate the year
- xbInt16 iYear = (xbInt16)(lJulDays / 365.24 );
- lJulDays -= (iYear * 365L) + (iYear / 4L) - (iYear / 100L) + (iYear / 400L);
- iYear++;
- while( lJulDays <= 0 ){
- iYear--;
- lJulDays += (365L + IsLeapYear( iYear ));
- }
- // this for loop calculates the month by comparing the number of days remaining to one of the tables
- xbInt16 iIsLeap = IsLeapYear(iYear);
- xbInt16 iMonth = 1;
- while( ((xbInt16) lJulDays > iAggregatedDaysInMonths[iIsLeap][iMonth]) && (iMonth < 12) )
- iMonth++;
-
- lJulDays -= iAggregatedDaysInMonths[iIsLeap][iMonth-1];
- sDate8.Sprintf( "%04d%02d%02ld", iYear, iMonth, lJulDays );
- return XB_NO_ERROR;
+ lJulDays -= JUL_OFFSET;
+ // calculate the year
+ xbInt16 iYear = (xbInt16)(lJulDays / 365.24 );
+ lJulDays -= (iYear * 365L) + (iYear / 4L) - (iYear / 100L) + (iYear / 400L);
+ iYear++;
+ while( lJulDays <= 0 ){
+ iYear--;
+ lJulDays += (365L + IsLeapYear( iYear ));
+ }
+ // this for loop calculates the month by comparing the number of days remaining to one of the tables
+ xbInt16 iIsLeap = IsLeapYear(iYear);
+ xbInt16 iMonth = 1;
+ while( ((xbInt16) lJulDays > iAggregatedDaysInMonths[iIsLeap][iMonth]) && (iMonth < 12) )
+ iMonth++;
+ lJulDays -= iAggregatedDaysInMonths[iIsLeap][iMonth-1];
+ sDate8.Sprintf( "%04d%02d%02ld", iYear, iMonth, lJulDays );
+ return XB_NO_ERROR;
}
/*************************************************************************/
//! @brief Set the date to the last day of month for a given date.
@@ -663,7 +717,8 @@ xbInt16 xbDate::JulToDate8( xbInt32 lJulDays )
\returns XB_NO_ERROR
*/
xbInt16 xbDate::LastDayOfMonth(){
- sDate8.Sprintf( "%4.4d%2.2d%2.2d", YearOf(), MonthOf(), iDaysInMonths[IsLeapYear()][MonthOf()]);
+ if( !IsNull())
+ sDate8.Sprintf( "%4.4d%2.2d%2.2d", YearOf(), MonthOf(), iDaysInMonths[IsLeapYear()][MonthOf()]);
return XB_NO_ERROR;
};
/*************************************************************************/
@@ -672,27 +727,33 @@ xbInt16 xbDate::LastDayOfMonth(){
\returns The month of the date.
*/
xbInt16 xbDate::MonthOf() const {
- xbInt16 iOutMonth;
- char month[3];
- month[0] = sDate8[5];
- month[1] = sDate8[6];
- month[2] = 0x00;
- iOutMonth = atoi( month );
- return iOutMonth;
+ if( !IsNull()){
+ xbInt16 iOutMonth;
+ char month[3];
+ month[0] = sDate8[5];
+ month[1] = sDate8[6];
+ month[2] = 0x00;
+ iOutMonth = atoi( month );
+ return iOutMonth;
+ } else {
+ return 0;
+ }
}
/*************************************************************************/
//! @brief Set the date.
/*!
\param sDateIn - Input date.
- \returns XB_NO_ERROR<br>XB_INVALID_DATE
+ \returns XB_NO_ERROR
*/
xbInt16 xbDate::Set( const xbString & sDateIn ){
+
if( DateIsValid( sDateIn )){
sDate8 = sDateIn;
- return XB_NO_ERROR;
+ } else {
+ sDate8 = ""; // set to null date if invalid date
}
- return XB_INVALID_DATE;
+ return XB_NO_ERROR;
}
/*************************************************************************/
//! @brief This routine sets up static data tables on startup.
@@ -790,13 +851,17 @@ xbInt16 xbDate::Sysdate(){
\returns The year of the date.
*/
xbInt16 xbDate::YearOf() const {
- char year[5];
- year[0] = sDate8[1];
- year[1] = sDate8[2];
- year[2] = sDate8[3];
- year[3] = sDate8[4];
- year[4] = 0x00;
- xbInt16 iOutYear = atoi( year );
- return iOutYear;
+ if( !IsNull()){
+ char year[5];
+ year[0] = sDate8[1];
+ year[1] = sDate8[2];
+ year[2] = sDate8[3];
+ year[3] = sDate8[4];
+ year[4] = 0x00;
+ xbInt16 iOutYear = atoi( year );
+ return iOutYear;
+ } else {
+ return 0;
+ }
};
} /* namespace */ \ No newline at end of file