65.9K
CodeProject 正在变化。 阅读更多。
Home

一个简单的日期处理类

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.78/5 (20投票s)

1999年12月13日

viewsIcon

222873

downloadIcon

4419

一个简化常见日期处理任务的类。

引言

用于开发此类算法的所有算法都可以在 这里 找到,该类 在此

要在您的项目中使用的该类,您将需要以下文件

  1. SimpleDate.cpp:包含日期类函数
  2. SimpleDate.h:上面类的头文件
  3. Parseit.cpp:用于解析日期字符串的辅助类
  4. Parseit.h:上面类的头文件

在编写业务应用程序时,人们不得不以多种形式处理日期。一个用于操作日期的简单轻量级类不是 MFC 或 WIN API 的一部分。有可用的类可以做到这一点,但其成本和复杂性在大多数情况下可能并非真正需要。我的通用需求是

  1. 易用性
  2. 能够轻松地将日期存储在结构、数据库、平面文件等中。
  3. 能够对日期进行简单的数学运算,例如将任意数量的月、日、年加到给定日期
  4. 能够处理 2 位和 4 位年份(在合理范围内)
  5. 处理不同的日期格式
  6. 能够轻松地对日期进行逻辑比较
  7. 能够使用标准的 MFC 体系结构处理用户输入并应用格式和有效性检查
  8. 我是否提到了易用性?

我最终开发了一个名为 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 的字符 stringCString 作为第一个参数。可选的格式类型是第二个参数。

用法示例: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
}

许可证

本文未附加明确的许可证,但可能在文章文本或下载文件本身中包含使用条款。如有疑问,请通过下面的讨论区联系作者。

作者可能使用的许可证列表可以在此处找到。

用于处理日期的简单类 - CodeProject - 代码之家
© . All rights reserved.