home *** CD-ROM | disk | FTP | other *** search
- /*------------------------------------------------------------*/
- /* filename - tdate.cpp */
- /* */
- /* function(s) */
- /* TDate member functions */
- /*------------------------------------------------------------*/
-
- /*------------------------------------------------------------*/
- /* */
- /* Turbo Vision Extensions -- Version 1.1.1 */
- /* */
- /* */
- /* Portions Copyright (c) 1991 by Borland International */
- /* All Rights Reserved. */
- /* */
- /* TV Extensions are Copyright (c) 1992 by Michael Bonner */
- /* These extensions may be freely used by any programmer */
- /* including royalty free inclusion in any commercial */
- /* application, but any commercial rights to the source */
- /* code or object files of the Extensions are reserved. */
- /* */
- /* This class is derived from the DATECL.ZIP from the C++
- library of compuserves BPROGB forum.
- Author.......: Chris Hill & Eric Simon
- Copyright....: None. Use freely.
- Version......: 3.10
- Usage........: General purpose date conversion, arithmetic, comparison,
- .............: and formatting class
-
- Acknowledgements:
-
- Originally inspired by Steve Marcus (CIS 72007,1233) 6/16/91
- Enhanced by Eric Simon (CIS 70540,1522) 6/29/91
- Further Enhanced by Chris Hill (CIS 72030,2606) 7/11/91
- Still Further Enhanced by Hill & Simon 8/05/91
- --------------------------------------------------------------*/
-
- #define Uses_TDate
- #include "tfield.h"
-
- const char *dayname[] = {"Sunday","Monday","Tuesday","Wednesday",
- "Thursday","Friday","Saturday"} ;
-
- const char *mname[] = {"January","February","March","April","May",
- "June","July","August","September","October","November","December"};
-
- ////////////////////////////////////////////////////////////
- // TParser Routines
- ////////////////////////////////////////////////////////////
- // extract words from string and insert them in collection
- //
- // TODO: Optimize this routine!
- //
- void TParser::parse( char *line )
- {
- char *curr;
- char *first;
-
- char temp[2];
-
- char wstr[maxLine];
- char ch = EOS;
- Boolean inword;
-
- curr = first = line;
- inword = False;
-
- while( (ch = *curr) != EOS )
- {
- if( inword )
- {
- if ( isgraph( ch ) )
- {
- if (strchr( "/-.", ch))
- {
- inword = False;
- strncpy( wstr, first, size_t(curr - first + 1) );
- wstr[size_t(curr-first + 1)]=EOS;
- insert( newStr( wstr ) );
- };
- }
- else
- {
- inword = False;
- strncpy( wstr, first, size_t(curr - first) );
- wstr[size_t(curr-first)]=EOS;
- insert( newStr( wstr ) );
- };
- }
- else
- {
- if ( isgraph( ch ) )
- {
- inword = True;
- first = curr;
- };
- }
- curr++;
- }
-
- if( inword )
- // grab last word if final char before null is alfa-num
- {
- strncpy( wstr, first, size_t(curr - first) );
- wstr[size_t(curr-first)]=EOS;
- insert( newStr( wstr ));
- }
- }
-
-
- ////////////////////////////////////////////////////////////
- // TDate Constructors
- ////////////////////////////////////////////////////////////
-
- int TDate::displayFormat=MDY;
- unsigned char TDate::displayOptions='\0';
-
- TDate::TDate()
- {
- tdate_month = tdate_day = tdate_year = julian = day_of_week = 0;
- }
-
- TDate::TDate (const long aJulDate, const long offset) :
- julian(aJulDate + offset)
- {
- if (julian != 0)
- julian_to_mdy ();
- else
- tdate_month = tdate_day = tdate_year = day_of_week = 0;
- }
-
- TDate::TDate (const int m, const int d, const int y) :
- tdate_month(m),
- tdate_day(d),
- tdate_year(y)
- {
- mdy_to_julian ();
- }
-
- TDate::TDate (char *dat)
- {
- setDate( dat );
- }
-
- TDate::TDate (const date &ds)
- {
- tdate_month = ds.da_mon;
- tdate_day = ds.da_day;
- tdate_year = ds.da_year;
- mdy_to_julian ();
- }
-
- TDate::TDate (const TDate &dt)
- {
- tdate_month = dt.tdate_month;
- tdate_day = dt.tdate_day;
- tdate_year = dt.tdate_year;
- mdy_to_julian ();
- displayFormat = dt.displayFormat;
- displayOptions = dt.displayOptions;
- }
-
- //////////////////////////////////////////////////////////////
- // TDate Arithmetic
- //////////////////////////////////////////////////////////////
-
- TDate TDate::operator + (const long i)
- {
- return TDate(julian + i);
- }
-
- TDate TDate::operator - (const long i)
- {
- return TDate(julian - i);
- }
-
- long TDate::operator - (const TDate &dt)
- {
- return ( julian - dt.julian );
- }
-
- TDate &TDate::operator += (const long i)
- {
- julian += i;
- julian_to_mdy();
- return *this;
- }
-
- TDate &TDate::operator -= (const long i)
- {
- julian -= i;
- julian_to_mdy();
- return *this;
- }
-
- TDate &TDate::operator ++ ( void ) // pre increment
- {
- julian++;
- julian_to_mdy();
- return *this;
- }
-
- #pragma argsused
- TDate &TDate::operator ++ ( int aDummyNumber ) // post increment
- {
- julian++;
- julian_to_mdy();
- return *this;
- }
-
- TDate &TDate::operator -- ( void ) // pre decrement
- {
- julian--;
- julian_to_mdy();
- return *this;
- }
-
- #pragma argsused
- TDate &TDate::operator -- ( int aDummyNumber ) // post decrement
- {
- julian--;
- julian_to_mdy();
- return *this;
- }
-
- //////////////////////////////////////////////////////////////
- // TDate comparison
- //////////////////////////////////////////////////////////////
-
- int operator < (const TDate &dt1, const TDate &dt2)
- {
- return ( dt1.julian < dt2.julian );
- }
-
- int operator <= (const TDate &dt1, const TDate &dt2)
- {
- return ( (dt1.julian == dt2.julian) || (dt1.julian < dt2.julian) );
- }
-
- int operator > (const TDate &dt1, const TDate &dt2)
- {
- return ( dt1.julian > dt2.julian );
- }
-
- int operator >= (const TDate &dt1, const TDate &dt2)
- {
- return ( (dt1.julian == dt2.julian) || (dt1.julian > dt2.julian) );
- }
-
- int operator == (const TDate &dt1, const TDate &dt2)
- {
- return ( dt1.julian == dt2.julian );
- }
-
- int operator != (const TDate &dt1, const TDate &dt2)
- {
- return ( dt1.julian != dt2.julian );
- }
-
- ////////////////////////////////////////////////////////////////
- // Ostream operations
- ////////////////////////////////////////////////////////////////
-
- ostream &operator << (ostream &os, const TDate &dt)
- {
- return os << dt.formatDate(MDY);
- }
-
- ostream &operator << (ostream &os, const date &dt)
- {
- return os << (int)dt.da_mon << "/" << (int)dt.da_day << "/" << dt.da_year;
- }
-
- //////////////////////////////////////////////////////////////
- // Conversion routines
- //////////////////////////////////////////////////////////////
-
- int TDate::char_to_month ( const char *charMonth )
- {
- // Convert charMonth to a numeric month value
- // Checks only first 2 or 3 characters for a match
- // JA FE MAR AP MAY JUN JUL AU SE OC NO DE
-
- int retMonth = 0; // 0 returned for invalid month name
-
- if (strlen(charMonth) > 0 )
- {
- char *upperMonth = strupr( strdup(charMonth) );
-
- switch (upperMonth[0])
- {
-
- case 'A':
- if (upperMonth[1] == 'P')
- retMonth = 4;
- if (upperMonth[1] == 'U')
- retMonth = 8;
- break;
-
- case 'D':
- if (upperMonth[1] == 'E')
- retMonth = 12;
- break;
-
- case 'F':
- if (upperMonth[1] == 'E')
- retMonth = 2;
- break;
-
- case 'J':
- if (upperMonth[1] == 'A')
- retMonth = 1;
- else {
- if ( upperMonth[1] == 'U' ) {
- if (upperMonth[2] == 'N')
- retMonth = 6;
- if (upperMonth[2] == 'L')
- retMonth = 7;
- };
- };
- break;
-
- case 'M':
- if (upperMonth[1] == 'A')
- {
- if (upperMonth[2] == 'R')
- retMonth = 3;
- if (upperMonth[2] == 'Y')
- retMonth = 5;
- };
- break;
-
- case 'N':
- if (upperMonth[1] == 'O')
- retMonth = 11;
- break;
-
- case 'O':
- if (upperMonth[1] == 'C')
- retMonth = 10;
- break;
-
- case 'S':
- if (upperMonth[1] == 'E')
- retMonth = 9;
- break;
-
- };
- };
-
- return retMonth; // 1 - 12 for valid month name, otherwise 0
-
- }
-
- void TDate::julian_to_wday (void)
- {
- day_of_week = (int) ((julian + 2) % 7 + 1);
- }
-
- void TDate::julian_to_mdy (void)
- {
- long a,b,c,d,e,z,alpha;
- z = julian+1;
- // dealing with Gregorian calendar reform
- if (z < 2299161L)
- a = z;
- else
- {
- alpha = (long) ((z-1867216.25) / 36524.25);
- a = z + 1 + alpha - alpha/4;
- }
- b = ( a > 1721423 ? a + 1524 : a + 1158 );
- c = (long) ((b - 122.1) / 365.25);
- d = (long) (365.25 * c);
- e = (long) ((b - d) / 30.6001);
- tdate_day = (int) b - d - (long)(30.6001 * e);
- tdate_month = (int) (e < 13.5) ? e - 1 : e - 13;
- tdate_year = (int) (tdate_month > 2.5 ) ? (c - 4716) : c - 4715;
- julian_to_wday ();
- }
-
- void TDate::mdy_to_julian (void)
- {
- int a,b=0;
- int work_month=tdate_month, work_day=tdate_day, work_year=tdate_year;
- // correct for negative year
- if (work_year < 0)
- work_year++;
- if (work_month <= 2)
- { work_year--; work_month +=12; }
-
- // deal with Gregorian calendar
- if (work_year*10000. + work_month*100. + work_day >= 15821015.)
- {
- a = work_year/100.;
- b = 2 - a + a/4;
- }
- julian = (long) (365.25*work_year) +
- (long) (30.6001 * (work_month+1)) + work_day + 1720994L + b;
- julian_to_wday ();
- }
-
- ////////////////////////////////////////////////////////////////
- // Format routine
- ////////////////////////////////////////////////////////////////
-
- char *TDate::formatDate (int type) const
- {
- char buf[40];
- strnset( buf, '\0', sizeof(buf) );
-
- if ( type == -1 )
- type = displayFormat;
-
- switch ( type )
- {
- case DAY:
- if ( (day_of_week < 1) || (day_of_week > 7) )
- strcpy(buf,"invalid day");
- else
- strncpy( buf, dayname[day_of_week-1],
- (displayOptions & DATE_ABBR) ? ABBR_LENGTH : 9);
- break;
-
- case MONTH:
- if ( (tdate_month < 1) || (tdate_month > 12) )
- strcpy(buf,"invalid month");
- else
- strncpy( buf, mname[tdate_month-1],
- (displayOptions & DATE_ABBR) ? ABBR_LENGTH : 9);
- break;
-
- case FULL:
- if ( (tdate_month < 1) || (tdate_month > 12) || (day_of_week < 0) ||
- (day_of_week > 7) )
- {
- strcpy(buf,"invalid date");
- }
- else
- {
- strncpy( buf, dayname[day_of_week-1],
- (displayOptions & DATE_ABBR) ? ABBR_LENGTH : 9);
- strcat( buf, ", ");
- strncat( buf, mname[tdate_month-1],
- (displayOptions & DATE_ABBR) ? ABBR_LENGTH : 9);
- strcat( buf, " ");
- sprintf( buf+strlen(buf), "%d, %d", tdate_day, abs(tdate_year) );
- if (tdate_year < 0)
- strcat(buf," B.C.E.");
- }
- break;
-
- case EUROPEAN:
- if ( (tdate_month < 1) || (tdate_month > 12) || (day_of_week < 0) ||
- (day_of_week > 7) )
- {
- strcpy(buf,"invalid date");
- }
- else
- {
- sprintf(buf,"%d ", tdate_day);
- strncat(buf, mname[tdate_month-1],
- (displayOptions & DATE_ABBR) ? ABBR_LENGTH : 9);
- sprintf( buf+strlen(buf), " %d", abs(tdate_year) );
- if (tdate_year < 0)
- strcat(buf," B.C.E.");
- }
- break;
-
- case MDY:
- default:
- if (tdate_day==0 || tdate_month==0 || tdate_year==0)
- strcpy(buf,"invalid date");
- else
- sprintf( buf+strlen(buf), "%d/%d/%d", tdate_month, tdate_day,
- (displayOptions & NO_CENTURY) && (abs(tdate_year) > 1899)
- ? (abs(tdate_year) - (abs(tdate_year) / 100 * 100))
- : (abs(tdate_year)) );
- break;
- }
-
- return newStr(buf);
- }
-
-
- void TDate::setFormat( const int format )
- {
- displayFormat = format;
- }
-
- int TDate::setOption( const int option, const int action )
- {
- int retval = 0; // holds the return value
-
- switch ( option )
- {
- case NO_CENTURY:
- if ( action )
- displayOptions |= NO_CENTURY;
- else
- {
- displayOptions &= (~NO_CENTURY);
- }
- retval = 1;
- break;
- case DATE_ABBR:
- if ( action )
- displayOptions |= DATE_ABBR;
- else
- {
- displayOptions &= (~DATE_ABBR);
- }
- retval = 1;
- break;
- default:
- retval = 0;
- break;
- }
- return retval;
- }
-
- ////////////////////////////////////////////////////////////////
- // Date Setting Routines
- ////////////////////////////////////////////////////////////////
- //
- // TODO: Optimize this routine!
- //
- int TDate::setDate( const char *charDate )
- {
- int success = 0;
- char workDate[maxLine];
- strncpy( workDate, charDate, maxLine );
-
- char *temp;
-
- int tempvalue;
- tempvalue = 0;
-
- struct date temp_date;
-
- // Handle the "TODAY" option
- if ( (!stricmp(charDate, "TODAY")) ||
- ((strlen(charDate) == 1) && (charDate[0] == '*')) )
- {
- getdate(&temp_date);
-
- tdate_month = temp_date.da_mon;
- tdate_day = temp_date.da_day;
- tdate_year = temp_date.da_year;
-
- success = 1;
- };
-
- // Handle the empty string possibility
- if ( charDate[0] == '\0' )
- {
- tdate_month = tdate_day = tdate_year = julian = day_of_week = 0;
-
- success = 1; // not really, but we don't want the parse routine to get this
- };
-
- if (success == 0)
- {
- tdate_month = tdate_day = tdate_year = 0;
-
- TParser *datetokens = new TParser( 5, 5 );
- // in production code, check lowMemory here
-
- // parse the date
- datetokens->parse( workDate );
-
- if( datetokens->getCount() > 0 )
- {
- // check for alpha tokens
- for ( int i = 0; i < datetokens->getCount(); i++ )
- {
- temp = (char *) datetokens->at( i );
- if ( isalpha(temp[0]) )
- {
- if (tdate_month == 0)
- tdate_month = char_to_month( temp );
- if (tdate_month > 0)
- {
- datetokens->atFree( i );
- break;
- };
- };
- };
-
- // check for numeric tokens
- for ( i = 0; i < datetokens->getCount(); i++ )
- {
- temp = (char *) datetokens->at( i );
- if ( !isalpha(temp[0]) )
- {
- tempvalue = atoi(temp);
- switch (temp[strlen(temp) - 1])
- {
- case ',':
- if ( (tdate_day == 0) &&
- (tempvalue > 0) &&
- (tempvalue < 32) )
- {
- tdate_day = tempvalue;
- }
- else
- if ( (tdate_month == 0) &&
- (tempvalue > 0) &&
- (tempvalue < 13) )
- {
- tdate_month = tempvalue;
- }
- else
- if (tdate_year == 0)
- {
- if (temp[0] == '0')
- {
- tdate_year = tempvalue;
- }
- else
- {
- if ( (tempvalue > 0) &&
- (tempvalue < 100) )
- {
- getdate(&temp_date);
- tdate_year = temp_date.da_year - (temp_date.da_year % 100) + tempvalue;
- }
- else
- {
- tdate_year = tempvalue;
- };
- };
- };
-
- break;
-
- case '/':
- case '.':
- case '-':
- if ( (tdate_month == 0) &&
- (tempvalue > 0) &&
- (tempvalue < 13) )
- {
- tdate_month = tempvalue;
- }
- else
- if ( (tdate_day == 0) &&
- (tempvalue > 0 ) &&
- (tempvalue < 32) )
- {
- tdate_day = tempvalue;
- }
- else
- if (tdate_year == 0)
- {
- if (temp[0] == '0')
- {
- tdate_year = tempvalue;
- }
- else
- {
- if ( (tempvalue > 0) &&
- (tempvalue < 100) )
- {
- getdate(&temp_date);
- tdate_year = temp_date.da_year - (temp_date.da_year % 100) + tempvalue;
- }
- else
- {
- tdate_year = tempvalue;
- };
- };
- };
- break;
-
- default:
- if ( (tdate_month == 0) &&
- (tempvalue > 0) &&
- (tempvalue < 13) )
- {
- tdate_month = tempvalue;
- }
- else
- if ( (tdate_day == 0) &&
- (tempvalue > 0) &&
- (tempvalue < 32) )
- {
- tdate_day = tempvalue;
- }
- else
- if (tdate_year == 0)
- {
- if (temp[0] == '0')
- {
- tdate_year = tempvalue;
- }
- else
- {
- if ( (tempvalue > 0) &&
- (tempvalue < 100) )
- {
- getdate(&temp_date);
- tdate_year = temp_date.da_year - (temp_date.da_year % 100) + tempvalue;
- }
- else
- {
- tdate_year = tempvalue;
- };
- };
- };
-
- break;
- };
- };
- };
- datetokens->freeAll();
- TParser::destroy(datetokens);
- };
-
- if ( (tdate_month > 0) &&
- (tdate_day > 0 ) &&
- (tdate_year == 0) )
- {
- getdate(&temp_date);
- tdate_year = temp_date.da_year;
- };
-
- if ( (tdate_month > 0) &&
- (tdate_day == 0) &&
- (tdate_year > 0) )
- {
- tdate_day = 1;
- };
-
- if ( (tdate_month > 0) &&
- (tdate_day > 0) &&
- (tdate_year != 0) )
- success = 1;
- };
-
- // validate the date
- if (tdate_day > 0)
- switch (tdate_month)
- {
- case 1:
- case 3:
- case 5:
- case 7:
- case 8:
- case 10:
- case 12:
- if (tdate_day > 31)
- success = tdate_month = tdate_day = tdate_year = 0;
- break;
-
- case 4:
- case 6:
- case 9:
- case 11:
- if (tdate_day > 30)
- success = tdate_month = tdate_day = tdate_year = 0;
- break;
-
- case 2:
- if ( tdate_day > (isLeapYear() ? 29 : 28) )
- success = tdate_month = tdate_day = tdate_year = 0;
- break;
-
- default:
- success = tdate_month = tdate_day = tdate_year = 0;
- break;
- }
- else
- success = tdate_month = tdate_day = tdate_year = 0;
-
- if (success != 0)
- mdy_to_julian ();
-
- return success;
- }
-
- int TDate::setDate( const long aJulDate, const long offset)
- {
- julian = aJulDate + offset;
- julian_to_mdy();
-
- return 1;
- }
-
- void TDate::incrMonth(void)
- {
- if (tdate_month < 12)
- tdate_month++;
- else
- {
- tdate_month = 1;
- tdate_year++;
- };
-
- // validate the date
- switch (tdate_month)
- {
- case 4:
- case 6:
- case 9:
- case 11:
- if (tdate_day > 30)
- tdate_day = 30;
- break;
- case 2:
- if ( tdate_day > (isLeapYear() ? 29 : 28) )
- tdate_day = (isLeapYear() ? 29: 28);
- break;
- };
-
- mdy_to_julian ();
-
- }
-
- void TDate::decrMonth(void)
- {
- if (tdate_month > 1)
- tdate_month--;
- else
- {
- tdate_month = 12;
- tdate_year--;
- };
-
- // validate the date
- switch (tdate_month)
- {
- case 4:
- case 6:
- case 9:
- case 11:
- if (tdate_day > 30)
- tdate_day = 30;
- break;
- case 2:
- if ( tdate_day > (isLeapYear() ? 29 : 28) )
- tdate_day = (isLeapYear() ? 29: 28);
- break;
- };
-
- mdy_to_julian ();
-
- }
-
- void TDate::incrYear(void)
- {
- tdate_year++;
-
- // validate the date
- if (tdate_month == 2)
- if ( tdate_day > (isLeapYear() ? 29 : 28) )
- tdate_day = (isLeapYear() ? 29: 28);
-
- mdy_to_julian ();
- }
-
- void TDate::decrYear(void)
- {
- tdate_year--;
-
- // validate the date
- if (tdate_month == 2)
- if ( tdate_day > (isLeapYear() ? 29 : 28) )
- tdate_day = (isLeapYear() ? 29: 28);
-
- mdy_to_julian ();
- }
-
- ///////////////////////////////////////////////////////////////
- // Miscellaneous Routines
- ///////////////////////////////////////////////////////////////
-
- long TDate::julDate( void ) const
- {
- return julian;
- }
-
- long TDate::PXDate( void ) const
- {
- return julian - PXOffset;
- }
-
- int TDate::day( void ) const
- {
- return tdate_day;
- }
-
- int TDate::dow( void ) const
- {
- return day_of_week;
- }
-
- int TDate::month( void ) const
- {
- return tdate_month;
- }
-
- int TDate::year( void ) const
- {
- return tdate_year;
- }
-
- int TDate::dayOfYear( void ) const
- {
- TDate temp( 1, 1, tdate_year );
-
- return (int) (julian - temp.julian + 1);
- }
-
-
- int TDate::isLeapYear( void ) const
- {
- return ( (tdate_year >= 1582) ?
- (tdate_year % 4 == 0 && tdate_year % 100 != 0 || tdate_year % 400 == 0 ):
- (tdate_year % 4 == 0) );
- }
-
- date TDate::eom( void ) const
- {
- date eom_temp;
- TDate tempdate( (tdate_month % 12) + 1, 1, tdate_year);
- if (tdate_month == 12)
- tempdate.tdate_year++;
- --tempdate;
-
- eom_temp.da_year = tempdate.tdate_year;
- eom_temp.da_mon = tempdate.tdate_month;
- eom_temp.da_day = tempdate.tdate_day;
-
- return eom_temp;
- }
-
- date TDate::getDate( void ) const
- {
- date getDate_temp;
- getDate_temp.da_year = tdate_year;
- getDate_temp.da_mon = tdate_month;
- getDate_temp.da_day = tdate_day;
- return getDate_temp;
- }