⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 date.cpp

📁 C++时间类
💻 CPP
字号:
#include "date.h"
#include "ctype.h"
#include "time.h"

int Date::DisplayFormat=Date::MDY;
char Date::cbuf[Date::BUF_SIZE];

int Date::DisplayOptions=0;

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"};

static int GauDays[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };

////////////////////////////////////////////////////////////
// Constructors
////////////////////////////////////////////////////////////

Date::Date()
{
    month = day = day_of_week = 0;
    year = 0;
    julian = 0;
}

Date::Date (long j) : julian(j)
{
    julian_to_mdy ();
}

Date::Date (int m, int d, int y) : month(m), day(d), year(y)
{
    mdy_to_julian ();
}

Date::Date (const char *dat)
{  
    if (!strcmp(dat, "TODAY"))       //strcmp  相等返回0 
	{


		time_t curtime=time(0);
		tm tim =*localtime(&curtime);

		day=tim.tm_mday;
		month=tim.tm_mon+1;
		year=tim.tm_year+1900;
	}
	else
	{
        char *tmp, *tmp2;
        int  nlen=strlen(dat), i, datetype;

        tmp = new char[nlen+1];

        //
		//  TML - We need to make a copy of 'dat' because strtok() modifies
		//  the content of its first parameter!!!
		//
        strcpy(tmp, dat);

        //
        //  Possible date string formats are those that are generated by the
        //  Date class itself!  The corresponding possible string lengths are
        //  also listed (with ranges from shortest to longest string for that
        //  format).
        //
        //  MDY:        03/23/1993                      => 6-10,13-17
        //  EUROPEAN:   23 March 1993                   => 13, 20
        //  FULL,ABBR.: Tue, Mar 23, 1993               => 16-17, 23-24
        //  FULL:       Tuesday, March 23, 1993         => 22-23, 29-30
        //
        //  These dates may also have B.C.E. appended at the end, thus we have
        //  the second set of string lengths with 7 more characters!
        //

        if (isalpha(tmp[0]))
            datetype = Date::FULL;
        else if (nlen == 20)
			datetype = Date::EUROPEAN;
		else if (nlen == 13)
			datetype = (isalpha(tmp[5]) ? Date::EUROPEAN : Date::MDY);
		else
			datetype = Date::MDY;

        switch(datetype)
        {
            case Date::EUROPEAN:
                day   = atoi(strtok(tmp," "));

                tmp2 = strtok(NULL," ");
                i = 0;
                while (i < 12)
                {
                   // #ifdef _MSC
                   // if (_stricmp(tmp2, mname[i++]) == 0)
                   // #else
                    if (_stricmp(tmp2, mname[i++]) == 0)
                   // #endif
                        break;
                }

                month = (i <= 12) ? i : 0;
                year  = atoi(strtok(NULL," "));
                break;

            case Date::FULL:
                strtok(tmp," ");                // Skip the day info
                tmp2 = strtok(NULL," ");        // Get the month string

                i = -1;
                while (++i < 12)
                {
                    if (toupper(tmp2[0]) == toupper(*(mname[i]))    &&
                        toupper(tmp2[1]) == toupper(*(mname[i]+1))  &&
                        toupper(tmp2[2]) == toupper(*(mname[i]+2)))
                        break;
                }

                month = (i <= 12) ? ++i : 0;
                day   = atoi(strtok(NULL,","));
                year  = atoi(strtok(NULL," "));
                break;

            default:
				if(tmp[4]=='-')
				{
					
					year  = atoi(strtok(tmp,"-"));
					month = atoi(strtok(NULL,"-"));
					day   = atoi(strtok(NULL," "));
				}
				else 
				{
					month = atoi(strtok(tmp,"/-"));
					day   = atoi(strtok(NULL,"/-"));
					year  = atoi(strtok(NULL," "));
				}
                break;
        }

        //
        //  Convert B.C.E. year to proper value!
        //
		if (strtok(NULL, ".") != NULL)
            year *= -1;

        //
        //  Verify values!
        //
        if ((month < 1) || (month > 12) || (day < 1) || (day >  DaysInMonth()))
        {
            month = day = 0;
            year = 0;
		}

		delete [] tmp;
	}

    mdy_to_julian ();
}

Date::Date (const DOSDATE_T &ds)
{
    month = ds.month;
	day   = ds.day;
	year  = ds.year;
    mdy_to_julian ();
}

Date::Date (const Date &dt)
{
    month = dt.month;
	day   = dt.day;
	year  = dt.year;
    mdy_to_julian ();
}

//////////////////////////////////////////////////////////////
// Conversion operations
//////////////////////////////////////////////////////////////
Date::operator char *( void )
{
    formatDate();
    return cbuf;
}

//////////////////////////////////////////////////////////////
// Date Arithmetic
//////////////////////////////////////////////////////////////
Date Date::operator + (long i)
{
    return Date(julian + i);
}

Date Date::operator + (int i)
{
    return Date(julian + (long)i);
}

Date Date::operator - (long i)
{
    return Date(julian - i);
}

Date Date::operator - (int i)
{
    return Date(julian - (long)i);
}

long Date::operator - (const Date &dt)
{
	return ( julian - dt.julian );
}

const Date &Date::operator += (long i)
{
	julian += i;
	julian_to_mdy();
	return *this;
}

const Date &Date::operator -= (long i)
{
	julian -= i;
	julian_to_mdy();
	return *this;
}

Date Date::operator ++()
{
    julian++;
	julian_to_mdy();
	return *this;
}

Date Date::operator ++(int)
{
    Date temp=*this;                    // TML - Necessary to save current
                                        // value of (*this) in order to
    julian++;                           // simulate postfix operation!
	julian_to_mdy();
    return temp;
}

Date Date::operator --()
{
    julian--;
	julian_to_mdy();
    return *this;
}

Date Date::operator --(int)
{
    Date temp=*this;                    // TML - Necessary to save current
                                        // value of (*this) in order to
    julian--;                           // simulate postfix operation!
	julian_to_mdy();
    return temp;
}

//////////////////////////////////////////////////////////////
// Date comparison
//////////////////////////////////////////////////////////////
int Date::operator <  (const Date &dt)
{
    return ( julian < dt.julian );
}

int Date::operator <= (const Date &dt)
{
    return ( (julian == dt.julian) || (julian < dt.julian) );
}

int Date::operator >  (const Date &dt)
{
    return ( julian > dt.julian );
}

int Date::operator >= (const Date &dt)
{
    return ( (julian == dt.julian) || (julian > dt.julian) );
}

int Date::operator == (const Date &dt)
{
    return ( julian == dt.julian );
}

int Date::operator != (const Date &dt)
{
    return ( julian != dt.julian );
}

////////////////////////////////////////////////////////////////
// Ostream operations
////////////////////////////////////////////////////////////////

ostream &operator << (ostream &os, const Date &dt)
{
	return os << dt.formatDate();
}

ostream &operator << (ostream &os, const DOSDATE_T &dt)
{
	return os << (int)dt.month << "/" << (int)dt.day << "/" << dt.year;
}


//////////////////////////////////////////////////////////////
// Conversion routines
//////////////////////////////////////////////////////////////

void Date::julian_to_wday (void)
{
	day_of_week = ((julian + 2) % 7 + 1);
}

void Date::julian_to_mdy ()
{
	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);

	day = b - d - (long)(30.6001 * e);
	month = (e < 13.5) ? e - 1 : e - 13;
    year = (int)((month > 2.5 ) ? (c - 4716) : c - 4715);
	julian_to_wday ();
}

void Date::mdy_to_julian (void)
{
	int a,b=0;
	int work_month=month, work_day=day, work_year=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 = (int)(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
////////////////////////////////////////////////////////////////
const char *Date::formatDate (int type) const
{
	memset( cbuf, '\0', sizeof(cbuf) );

	switch ( type )
	{
		case Date::DAY:

			if ( (day_of_week < 1) || (day_of_week > 7) )
				strcpy(cbuf,"invalid day");
			else
				strncpy( cbuf, dayname[day_of_week-1],
					(DisplayOptions & Date::DATE_ABBR) ? ABBR_LENGTH : 9);
			break;

		case Date::MONTH:

			if ( (month < 1) || (month > 12) )
				strcpy(cbuf,"invalid month");
			else
				strncpy( cbuf, mname[month-1],
					(DisplayOptions & Date::DATE_ABBR) ? ABBR_LENGTH : 9);
			break;

		case Date::FULL:

            if ( (month < 1) || (month > 12) || (day_of_week < 1) ||
                 (day_of_week > 7) || (day < 1) )
			{
				strcpy(cbuf,"invalid date");
				break;
			}

			strncpy( cbuf, dayname[day_of_week-1],
				(DisplayOptions & Date::DATE_ABBR) ? ABBR_LENGTH : 9);
			strcat( cbuf, ", ");
			strncat( cbuf, mname[month-1],
				(DisplayOptions & Date::DATE_ABBR) ? ABBR_LENGTH : 9);
			sprintf( cbuf+strlen(cbuf), " %d, %d", day, abs(year) );

			if (year < 0)
				strcat(cbuf," B.C.E.");
			break;

		case Date::EUROPEAN:

			if ( (month < 1) || (month > 12) || (day_of_week < 1) ||
                 (day_of_week > 7) || (day < 1)  )
			{
				strcpy(cbuf,"invalid date");
				break;
			}

			sprintf(cbuf,"%d ",  day);
			strncat(cbuf, mname[month-1],
				(DisplayOptions & Date::DATE_ABBR) ? ABBR_LENGTH : 9);
			sprintf( cbuf+strlen(cbuf), " %d", abs(year) );

			if (year < 0)
				strcat(cbuf," B.C.E.");
			break;

		case Date::MDY:

		default:
            if ( (month < 1) || (month > 12) || (day_of_week < 1) ||
                 (day_of_week > 7) || (day < 1) )
            {
                strcpy(cbuf,"invalid date");
				break;
            }
            else
				sprintf( cbuf+strlen(cbuf), "%1d/%1d/%02d", month, day,
					(DisplayOptions & Date::NO_CENTURY) && (abs(year) > 1899)
					? (abs(year) - (abs(year) / 100 * 100))
					: (abs(year))  );
			break;
	}

	return cbuf;
}

void Date::setFormat( int format )
{
	DisplayFormat = format;
}

int Date::setOption( int option, int action )
{
    //
    // TML - Convert from switch statement to if statement
    //
    if (option & (Date::NO_CENTURY | Date::DATE_ABBR))
    {
        if ( action )
            DisplayOptions |= option;
        else
            DisplayOptions &= ~option;

        return 1;
    }
    else
        return 0;
}

///////////////////////////////////////////////////////////////
//  Miscellaneous Routines
///////////////////////////////////////////////////////////////

long Date::julDate( void ) const
{
	return julian;
}

int Date::DOY( void ) const
{
	Date temp( 1, 1, year );

	return (int) (julian - temp.julian + 1);
}


int Date::isLeapYear( void ) const
{
	return  ( (year >= 1582) ?
		  (year % 4 == 0  &&  year % 100 != 0  ||  year % 400 == 0 ):
		  (year % 4 == 0) );
}

DOSDATE_T Date::eom( void ) const
{
    static DOSDATE_T eom_temp;
	Date tempdate( (month % 12) + 1, 1, year);

	if (month == 12)
		tempdate.year++;

	tempdate--;

	eom_temp.year  = tempdate.year;
	eom_temp.month = tempdate.month;
	eom_temp.day   = tempdate.day;

	return eom_temp;
}

DOSDATE_T Date::getDate( void ) const
{
    static DOSDATE_T getDate_temp;

	getDate_temp.year  = year;
	getDate_temp.month = month;
	getDate_temp.day   = day;

	return getDate_temp;
}


//哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪?
// Version 4.0 Extension to Public Interface - CDP
//哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪?

const Date & Date::Set()
{


		time_t curtime=time(0);
		tm tim =*localtime(&curtime);

		day=tim.tm_mday;
		month=tim.tm_mon+1;
		year=tim.tm_year+1900;

	mdy_to_julian();
	return *this;
}

const Date & Date::Set(int nMonth, int nDay, int nYear)
{
	month = nMonth;
	year  = nYear < 0 ? 9999 : nYear;
	year  = nYear > 9999 ? 0 : nYear;
    day   = (nDay < DaysInMonth() ? nDay : DaysInMonth());

	mdy_to_julian();
	return *this;
}

const Date & Date::Set(long j)
{
	julian = j;

	julian_to_mdy();
	return *this;
}

 int Date::DaysInMonth()
{
	return GauDays[month-1] + (month==2 && isLeapYear());
}

 int Date::FirstDOM() const
{
	return Date(month, 1, year).NDOW();
}

 int Date::Day() const
{
	return day;
}

int Date::NDOW() const
{
	return day_of_week;
}

 int Date::NYear4() const
{
	return year;
}

 int Date::NMonth() const
{
	return month;
}

 const Date & Date::AddWeeks(int nCount)
{
	Set(julian + (long)nCount*7);
	return *this;
}


 const Date & Date::AddMonths(int nCount)
{
    nCount += month;                    // Since month is of type unsigned char
                                        // I choose to use nCount as the main
    while (nCount < 1)                  // counter - TML
    {
        nCount += 12;
        year--;
    }

    while (nCount > 12)
    {
        nCount -= 12;
        year++;
    }

    month =  nCount;
	mdy_to_julian();
	return *this;
}

 const Date & Date::AddYears(int nCount)
{
	year += nCount;
	mdy_to_julian();
	return *this;
}

int Date::WOM()
{
	// Abs day includes the days from previous month that fills up
	// the begin. of the week.
	int nAbsDay = day + FirstDOM()-1;
	return (nAbsDay-NDOW())/7 + 1;
}

 int Date::WOY()
{
	Date   doTemp(1, 1, year);
	return (int)(((julian - doTemp.julian+1)/7) + 1);
}

 Date Date::BOM()
{
	return(Date(month, 1, year));
}

 Date Date::EOM()
{
    return(Date(month+1, 1, year)-1L);
}

 Date Date::BOY()
{
	return(Date(1, 1, year));
}

 Date Date::EOY()
{
    return(Date(1, 1, year+1)-1L);
}

 const char * Date::CMonth()
{
	return(formatDate(MONTH));
}

const char * Date::CDOW()
{
	return(formatDate(DAY));
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -