StarWing83, 你的耐心真让我佩服!!!
时不再来!!!
CLF_DateTime::CLF_DateTime(int year/*=1900*/,int month/*=1*/,int day/*=1*/, int hour/*=0*/,int min/*=0*/,int sec/*=0*/) { assert(year>=TM_TIMEBASE); assert(month>=0&&month<=11); assert(day>=1&&day<=31); assert(hour>=0&&hour<=23); assert(min>=0&&min<=59); assert(sec>=0&&sec<=59); tm_year=year-TM_TIMEBASE; tm_mon=month-1; tm_mday=day; tm_hour=hour; tm_min=min; tm_sec=sec; } char* CLF_DateTime::display( char* strdisplay ) { assert(strdisplay!=NULL); strftime(strdisplay,80,"%Y-%m-%d %H:%M:%S",this); //Remark From Terence: 在沒有測試strdisplay指針下使用指針 ( 指針使用安全) return strdisplay; }因为原先的代码就没有做这件事情,所以我忽略了,这是我的问题。因为是从别人的代码开始入手,我从一开始就忽略了一些必要的安全手法。平时写代码的时候我是很注意的,但是还不够。以后我会注意这方面的问题。
_VALIDATE_RETURN_ERRCODE( ( ( tb->tm_mday >= 1 ) && ( // Day is in valid range for the month ( ( _days[ tb->tm_mon + 1 ] - _days[ tb->tm_mon ] ) >= tb->tm_mday ) || // Special case for Feb in a leap year ( ( IS_LEAP_YEAR( tb->tm_year + 1900 ) ) && ( tb->tm_mon == 1 ) && ( tb->tm_mday <= 29 ) ) ) ), EINVAL )又及,上面是CRT对于日期(天)错误的判断,如果对assert仍然不满意,可以使用这个。
#ifndef _CLF_H_ #define _CLF_H_ #include <ctime> #define _YEAR_BASE 1900 #define _MAX_YEAR 138 /* 2038 is the max year */ class CLF_DateTime : public tm { public: enum FType {FT_SEC,FT_MIN,FT_HOUR,FT_DAY,FT_MON}; CLF_DateTime(int year=_YEAR_BASE,int month=1,int day=1, int hour=0,int min=0,int sec=0); ~CLF_DateTime(); void SetTime(int year,int month,int day,int hour,int min,int sec); time_t GetTime(); void Format(FType type); int Compare(CLF_DateTime& pb); char* Display(char* strdisplay); friend std::ostream& operator<<(std::ostream& o,CLF_DateTime& t); }; //内联函数 inline time_t CLF_DateTime::GetTime() { return mktime(this); } #endif在CLF.cpp中:
#include <iostream> using namespace std; #include "CLF.h" #include <assert.h>//注:请使用自己的断言头文件 #define STR_MAX 100 //使用了CRT的方法 const char _days[]={31,29,31,30,31,30,31,31,30,31,30,31}; //如果v1超过了v3指定的值,则v2进位 inline void _format( int& v1,int& v2,int v3 ) { if (v1>=v3)v2++; v1=0; } CLF_DateTime::CLF_DateTime( int year/*=_YEAR_BASE*/,int month/*=1*/,int day/*=1*/, int hour/*=0*/,int min/*=0*/,int sec/*=0*/ ) { SetTime(year,month,day,hour,min,sec); } CLF_DateTime::~CLF_DateTime() { } void CLF_DateTime::SetTime( int year/*=_YEAR_BASE*/,int month/*=1*/,int day/*=1*/, int hour/*=0*/,int min/*=0*/,int sec/*=0*/ ) { assert(year>=_YEAR_BASE && year<=_YEAR_BASE+_MAX_YEAR); assert(month>=1 && month<=12); assert(day>=1 && day<=_days[month-1]); assert(hour>=0 && hour<=23); assert(min>=0 && min<=59); assert(sec>=0 && sec<=59); tm_year=year-_YEAR_BASE; tm_mon=month-1; tm_mday=day; tm_hour=hour; tm_min=min; tm_sec=sec; } char* CLF_DateTime::Display( char* strdisplay ) { assert(strdisplay!=NULL); strftime(strdisplay,80,"%Y-%m-%d %H:%M:%S",this); return strdisplay; } //对时间四舍五入 void CLF_DateTime::Format(FType type ) { for (;;) { _format(tm_sec,tm_min,30); if (type==FT_SEC)break; _format(tm_min,tm_hour,30); if (type==FT_MIN)break; _format(tm_hour,tm_mday,12); if (type==FT_HOUR)break; _format(tm_mday,tm_mon,_days[tm_mon]/2); tm_mday++; if (type==FT_DAY)break; _format(tm_mon,tm_year,6); break; } //规格化时间 time_t temp=mktime(this); *this=(CLF_DateTime&)*localtime(&temp); } //比较函数,如果pb大返回-1,反之返回1,如果相等返回0 int CLF_DateTime::Compare( CLF_DateTime& pb ) { if (&pb==this)return 0; double temp=difftime(GetTime(),pb.GetTime()); if (temp>0)return 1; if (temp<0)return -1; return 0; } ostream& operator<<( ostream& o,CLF_DateTime& t ) { char str[STR_MAX]; return o<<t.Display(str); }在test.cpp中:
#include <iostream> #include "CLF.h" using namespace std; int main(){ CLF_DateTime t1(2000,2,29,23,59,59); CLF_DateTime t2(2000,2,12,11,13,12); //t2.Format(CLF_DateTime::FType(100));//不会出错 t2.Format(CLF_DateTime::FT_DAY); cout<<t2<<endl; cout<<(t2); getchar(); }