一个简单的日期处理类






4.78/5 (20投票s)
1999年12月13日

222873

4419
一个简化常见日期处理任务的类。
引言
用于开发此类算法的所有算法都可以在 这里 找到,该类 在此。
要在您的项目中使用的该类,您将需要以下文件
- SimpleDate.cpp:包含日期类函数
- SimpleDate.h:上面类的头文件
- Parseit.cpp:用于解析日期字符串的辅助类
- Parseit.h:上面类的头文件
在编写业务应用程序时,人们不得不以多种形式处理日期。一个用于操作日期的简单轻量级类不是 MFC 或 WIN API 的一部分。有可用的类可以做到这一点,但其成本和复杂性在大多数情况下可能并非真正需要。我的通用需求是
- 易用性
- 能够轻松地将日期存储在结构、数据库、平面文件等中。
- 能够对日期进行简单的数学运算,例如将任意数量的月、日、年加到给定日期
- 能够处理 2 位和 4 位年份(在合理范围内)
- 处理不同的日期格式
- 能够轻松地对日期进行逻辑比较
- 能够使用标准的 MFC 体系结构处理用户输入并应用格式和有效性检查
- 我是否提到了易用性?
我最终开发了一个名为 CSimpleDate
的类。我认为它满足或超过了以上所有要求。所有数学函数都返回对自身的引用,以便它们可以用作赋值中的右值。内部,日期以儒略日期存储。有一个 long
类型的运算符可以返回此值,从而允许 CSimpleDate
成为比较或赋值中的右值。日期可以作为文本 string
(人类可读)或 long
存储在文件、数据库或结构中。以 long
形式存储的日期非常易于用作索引或进行快速日期比较,但普通人类不可读。任君选择。
由于我使用整数数学进行计算,因此我认为在预测久远的过去或未来的日期时,精度可能有点偏差。我将把这个问题留给算法爱好者们来决定。
使用示例
void CYourClass::Something()
{
CSimpleDate Date1; // will have today's date in it default constructor
CSimpleDate Date2("12/07/1941"); //Set to that date
CString s=(LPCSTR)Date2;// s will be "12/07/1941"
s = Date2.GetFullDateString();// s= "Sun Dec 07 1941"
s = Date2.GetFullDateStringLong();// s= "Sunday December 071941"
if(Date2 != "12/09/1940")
DoThis()
else
DoThat();
if(Date2 < Date1)
s="It Better be";
else
s="We Got Troubles";
Date2="02/29/2000";//copy type 1
Date2.AddYear(1)//Date2 now equals "02/28/2001"
Date2=Date;//copy type 2
Date=Date2.AddDays(1234) // Date and Date2 are both equal now see source code
long D1=(long)Date;// these functions are equivalent
long D2=Date2.GeyJulianDate();
}
还有理解该类的 DDX 函数。它们执行格式化和日期验证。
void CMainView::DoDataExchange(CDataExchange* pDX)
{
CFormView::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CMainView)
DDX_SimpleDate(pDX, IDC_THEDATE, m_TheDateString); // string or cstring
DDX_SimpleDate(pDX, IDC_THEDATE2, m_TheDataLong); // long
DDX_Text(pDX, IDC_RESULTS, m_R1);
//}}AFX_DATA_MAP
}
该类中内置了时间函数的实现。我只实现了非常基本的时间功能,因为我很少需要它。详情请参阅源代码。
有一个小型演示程序展示了该类的用法,还有一个包含该类和仅参考文本的文件。
CSimpleDate C++ 类文档
目录
构造函数和析构函数
CSimpleDate(int FormatType=MMDDYYYY);
CSimpleDate(LPCSTR DateString,int FormatType=MMDDYYYY);
CSimpleDate(long JD,int FormatType=MMDDYYYY);
virtual ~CSimpleDate();
日期数学例程
const CSimpleDate& AddDays(int Days);
const CSimpleDate& AddYears(int Yrs);
const CSimpleDate& AddMonths(int Mon);
const CSimpleDate& SubtractYears(int Yrs);
const CSimpleDate& SubtractDays(int Days);
const CSimpleDate& SubtractMonths(int Mon);
virtual int YearsOld();
数据访问例程
LPCSTR GetFullDateString();
LPCSTR GetFullDateStringLong();
virtual int GetDayOfWeek();
virtual BOOL IsValid();
long GetJulianDate();
virtual int GetDay()
virtual int GetMonth()
virtual int GetYear()
virtual void GetIntegerDate(int& m, int& d,int& y)
virtual int GetHour()
virtual int GetMin()
virtual int GetSeconds()
virtual void GetTimeString(CString& s,BOOL AmPm=TRUE);
virtual void GetTimeString(LPSTR s,int nLen,BOOL AmPm=TRUE);
virtual void GetTimeStringShort(CString& s,BOOL AmPm=TRUE);
virtual void GetTimeStringShort(LPSTR s,int nLen,BOOL AmPm=TRUE);
运算符赋值转换相等性等。
operator LPCSTR();
operator long();
const CSimpleDate& operator = (const CSimpleDate& Date);
const CSimpleDate& operator = (LPCSTR Date);
BOOL operator > (const CSimpleDate& Date);
BOOL operator < (const CSimpleDate& Date);
BOOL operator >= (const CSimpleDate& Date);
BOOL operator <= (const CSimpleDate& Date);
BOOL operator == (const CSimpleDate& Date);
BOOL operator != (const CSimpleDate& Date);
BOOL operator > (LPCSTR Date);
BOOL operator < (LPCSTR Date);
BOOL operator >= (LPCSTR Date);
BOOL operator <= (LPCSTR Date);
BOOL operator == (LPCSTR Date);
BOOL operator != (LPCSTR Date);
受保护的内部类成员
virtual BOOL SetToday();
virtual BOOL CSimpleDate::ParseDateString(LPCSTR,int& m,int& d,int& y);
virtual BOOL ParseDateString(LPCSTR);
virtual long ConvertToJulian( int month,int day,int year);
virtual long ConvertToJulian();
virtual void ConvertFromJulian(int& Month,int& Day,int& Year);
virtual void ConvertFromJulian();
virtual void AdjustDays();
virtual void SetTime();
静态成员函数
static BOOL VerifyDateFormat(LPCSTR date);
static BOOL FixDateFormat(CString & date);
static BOOL FixDateFormat(LPSTR date);
非成员数据交换函数
void DDX_SimpleDate(CDataExchange *pDX,int nID,LPSTR str,int nLen);
void DDX_SimpleDate(CDataExchange *pDX,int nID,CString& str);
void DDX_SimpleDate(CDataExchange *pDX,int nID,long& jdate);
构造函数
有三个可用的构造函数。第一个
CSimpleDate(int FormatType=MMDDYYYY);
会将对象初始化为今天的日期。这是默认构造函数。
用法示例:CSimpleDate D
; 或 CSimpleDate D(MMDDYY);
第二个
CSimpleDate(LPCSTR DateString,int FormatType=MMDDYYYY);
将包含格式正确的 date
的字符 string
或 CString
作为第一个参数。可选的格式类型是第二个参数。
用法示例:CSimpleDate("12/07/1999");
或 CSimpleDate("12/07/99",MMDDYY);
一个注意事项;日期的内部表示始终保持为 4 位年份,无论生效的格式如何。格式仅影响输出。
第三个
CSimpleDate(long JD,int FormatType=MMDDYYYY);
将代表 儒略日期编号 的 long
整数作为参数,以及可选的格式类型。
日期数学
const CSimpleDate& AddDays(int Days);
const CSimpleDate& AddYears(int Yrs);
const CSimpleDate& AddMonths(int Mon);
const CSimpleDate& SubtractYears(int Yrs);
const CSimpleDate& SubtractDays(int Days);
const CSimpleDate& SubtractMonths(int Mon);
virtual int YearsOld();
这些例程不言自明。它们将获取一个现有的 CSimpleDate
对象并对其执行请求的操作。除了 YearsOld()
之外,它们都返回对自身的引用,允许它们用作表达式的右侧。例如,请看以下几行代码。
CSimpleDate Date("12/12/1990"); // Date=dec 12 1990
CSimpeDate Date2; // Date2 = todays date
Date2 = Date.AddMonths(1); // date2 now equals Jan 12 1991 and so does Date1.
copy
构造函数被调用,可以以这种方式进行赋值。
YearsOld()
返回 CSimpleDate
值与今天日期之间完整年数。今天的日期是当前的系统日期。不会返回负值,最小值为 0
。如果 CSimpleDate
对象无效或包含大于今天的日期,则返回 0
。
类访问函数
LPCSTR GetFullDateString();
返回一个包含日期(格式为“Sun Dec 7 1941
”)的 string
LPCSTR GetFullDateStringLong();
返回一个包含日期(格式为“Sunday December 7 1941
”)的 date
string
int GetDayOfWeek();
返回一个整数,表示星期几,其中 Sunday=1 Monday=2
等等。
BOOL IsValid();
如果 CSimpleDate
对象包含一个有效日期,则返回 TRUE
,否则返回 FALSE
;
long GetJulianDate();
返回一个 long int
,表示此 CSimpeDate
对象公历日期的儒略日期编号
int GetDay()
int GetMonth()
int GetYear()
void GetIntegerDate(int& m, int& d,int& y)
这些都返回整数,表示所请求对象的内部值
int GetHour()
int GetMin()
int GetSeconds()
这些都返回整数,表示所请求对象的内部值。GetHour
函数返回基于 24 小时制,不调整 AM/PM。
void GetTimeString(CString& s,BOOL AmPm=TRUE);
void GetTimeString(LPSTR s,int nLen,BOOL AmPm=TRUE);
返回一个表示当前系统时间的 string
。小时部分已调整为 12 小时制。如果 AmPm 为 true
(默认值),则会在 string
后面附加 AM 或 PM。返回的 string
格式为“9:45:55 PM
”。
void GetTimeStringShort(CString& s,BOOL AmPm=TRUE);
void GetTimeStringShort(LPSTR s,int nLen,BOOL AmPm=TRUE);
返回一个表示当前系统时间的 string
。小时部分已调整为 12 小时制。如果 AmPm 为 true(默认值),则会在 string
后面附加 AM 或 PM。返回的 string
格式为“9:45 PM
”。
运算符和比较函数
operator LPCSTR();
返回 CSimpledate
对象的 string
表示形式。这还允许使用 CSimpleDate
作为参数来构造 CSimpleDate
。
CSimpleDate Date("12/09/1946");
CString s=(LPCSTR)Date;
CSimpleDate S2(Date); // no such constructor but will work because it converts the Date to a LPCSTR
VERIFY(s=="12/09/1946");
operator long();
返回一个 long
,表示此 CSimpleDate
对象的儒略 Date
编号
CSimpleDate Date("12/09/1946");
long s=(long)Date;
VERIFY(s==Date.GetJulianDate());
const CSimpleDate& operator = (const CSimpleDate& Date);
const CSimpleDate& operator = (LPCSTR Date);
Copy
构造函数,基本功能,没什么特别的
BOOL operator > (const CSimpleDate& Date);
BOOL operator < (const CSimpleDate& Date);
BOOL operator > = (const CSimpleDate& Date);
BOOL operator < = (const CSimpleDate& Date);
BOOL operator == (const CSimpleDate& Date);
BOOL operator != (const CSimpleDate& Date);
BOOL operator > (LPCSTR Date);
BOOL operator < (LPCSTR Date);
BOOL operator > = (LPCSTR Date);
BOOL operator < = (LPCSTR Date);
BOOL operator == (LPCSTR Date);
BOOL operator != (LPCSTR Date);
这些都是重载的相等运算符,使用方式与普通情况相同。它们可以应用于 CSimpleDate
对象和/或日期的 string
表示形式(仅限右值)。例如
CSimpleDate Date("12/09/1998");
CSimpeDate Date2;
if ( Date2 > Date1)
{
DoThis();
}
else if(Date < "12/12/1998")
DoThis();
else
ForGetIt();
内部受保护函数
BOOL SetToday();
BOOL CSimpleDate::ParseDateString(LPCSTR,int& m,int& d,int& y);
BOOL ParseDateString(LPCSTR);
long ConvertToJulian( int month,int day,int year);
long ConvertToJulian();
void ConvertFromJulian(int& Month,int& Day,int& Year);
void ConvertFromJulian();
void AdjustDays();
void SetTime();
这些都用于设置和维护类数据。所有函数都是 virtual
的,因此可以在派生类中覆盖它们。名称本身就能很好地说明其功能。请检查源代码以了解每个成员的功能。
静态函数
BOOL VerifyDateFormat(LPCSTR date);
传入日期的 string
表示形式,例如“12/01/90
”或“12-08-1998
”,将确定日期是否正确并且格式是否为类可识别的格式。无效日期,例如“02/30/1998
”,也将被捕获。如果格式正确,则返回 true
,否则返回 false
。
BOOL FixDateFormat(CString & date);
BOOL FixDateFormat(LPSTR date);
这对函数将尝试格式化一个未格式化的 string
。未格式化的 string
是不包含日期分隔符的字符串,例如“121290
”或“12121997
”。如果成功,string
将被格式化并进行有效性检查。LPSTR 版本假定 string
的长度足以容纳格式化后的日期。
非成员函数
DDX_SimpleDate(CDataExchange *pDX,int nID,LPSTR str,int nLen);
DDX_SimpleDate(CDataExchange *pDX,int nID,CString& str);
DDX_SimpleDate(CDataExchange *pDX,int nID,long& jdate);
这些是数据交换函数,可用于输入和显示 CSimpleDate
类型的日期。需要保存到数据库或数据文件的数据仅限于日期的 string
表示形式或儒略日期编号。通过保存儒略日期编号,可以在日期字段之间进行快速的简单比较,例如大于、小于、等于。这些函数还提供错误检查,以确保输入的是有效日期。它们的使用方式与 MFC 提供的 DDX_xxx 函数完全相同。例如
void CMainView::DoDataExchange(CDataExchange* pDX)
{
CFormView::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CMainView)
DDX_SimpleDate(pDX, IDC_THEDATE, m_TheDate); // string or cstring
DDX_SimpleDate(pDX, IDC_THEDATE2, m_Date2); // long
DDX_Text(pDX, IDC_RESULTS, m_R1);
//}}AFX_DATA_MAP
}
许可证
本文未附加明确的许可证,但可能在文章文本或下载文件本身中包含使用条款。如有疑问,请通过下面的讨论区联系作者。
作者可能使用的许可证列表可以在此处找到。