zoukankan      html  css  js  c++  java
  • 软件架构设计之Utility模块——DateTime

    这里的日期实现比较简单:采用的是UTC日期(现在还不涉及到其他日期格式的转换如Gregorian日历),且以星期一作为每周的第一天。剩下的就看代码吧:

    头文件:

    class UTIL_API YKDateTime
    {
    public:
    	enum DT_FORM
    	{
    		DTF_YMDHMS1,		//%Y-%m-%d %H:%M:%S,中文格式选此
    		DTF_YMDHMS2,		//%m/%d/%Y %H:%M:%S
    		DTF_YMDHM1,		//%Y-%m-%d %H:%M,中文格式选此
    		DTF_YMDHM2,		//%Y/%m/%d %H:%M
    		DTF_YMD1,		//%Y-%m-%d,中文格式选此
    		DTF_YMD2,		//%Y/%m/%d
    		DTF_HMS1,		//%H:%M:%S,中文格式选此
    		DTF_HM1,			//%H:%M,中文格式选此
    		DTF_MDYHMS1,		//%m-%d-%Y %H:%M:%S
    		DTF_MDYHMS2,		//%m/%d/%Y %H:%M:%S
    		DTF_MDYHM1,		//%m-%d-%Y %H:%M
    		DTF_MDYHM2,		//%m/%d/%Y %H:%M
    		DTF_MDY1,		//%m-%d-%Y
    		DTF_MDY2,		//%m/%d/%Y
    	};
    
    	static YK_UINT PER_SECOND;
    	static YK_UINT PER_MINUTE;
    	static YK_UINT PER_HOUR;
    	static YK_UINT PER_DAY;
    	//static YK_UINT PER_MONTH;	每个月的天数并不相同,因此不定义
    	static YK_UINT PER_YEAR;
    public:
    	YKDateTime(YK_TM tm = 0);
    	YKDateTime(YK_INT nYear, YK_INT nMonth, YK_INT nDay, 
    		YK_INT nHour = 0, YK_INT nMinute = 0, YK_INT nSecond = 0);
    
    	~YKDateTime(void);
    
    	static YKDateTime GetLocalTime();
    
    	YKDateTime& operator=(YK_TM tm)
    	{ m_time = tm; return *this; }
    
    	// 是否是有效日期
    	YK_BOOL ValidDateTime();
    
    	YK_TM GetDateTime() const { return m_time; }
    	YKDateTime GetDate();			// 获取年月日
    	YK_INT GetYear() const;			// 获取年
    	YK_INT GetMonth() const;		// 获取月
    	YK_INT GetDay() const;			// 获取天
    	YK_INT GetHour() const;			// 获取小时
    	YK_INT GetMinute() const;		// 获取分钟
    	YK_INT GetSecond() const;		// 获取秒
    	YK_INT GetDayOfYear() const;	// 获取时间所在年的第几天
    	YK_INT GetDayOfMonth() const;	// 获取时间所在月的第几天
    	YK_INT GetDayOfWeek() const;	// 获取时间所在周的第几天,星期一作为第一天,(1~7)
    	YK_INT GetWeekOfYear() const;	// 获取时间所在年的第几周,星期一作为第一天,(1~54)
    	YK_INT GetWeekOfMonth() const;	// 获取时间所在月的第几周
    	YK_INT GetFirstDayOfWeek() const; // 获取时间所在周的第一天
    
    	YKString Format(DT_FORM dtf = DTF_YMDHMS1);
    	// 日期或时间中文格式化 XXXX年XX月XX日 XX时XX分XX秒
    	YKString FormatChs(DT_FORM dtf = DTF_YMDHMS1);
    	YKString FormatPostfix(YK_WCHAR postfix);
    	
    	// 从字符串中提取日期时间
    	static YKDateTime ParseDateTime(const YKString& str, DT_FORM tf = DTF_YMDHMS1);
    	static YKDateTime ParseDateTimeChs(const YKString& str, DT_FORM tf = DTF_YMDHMS1);
    
    	// 与当前时间相比,是否流逝了val秒
    	YK_BOOL IsElapsed(YK_TM val) const;
    	void AddSecond(YK_INT second)
    	{ *this += (second); }
    	void AddMinute(YK_INT minute)
    	{ AddSecond(minute*PER_MINUTE); }
    	void AddHour(YK_INT hour)
    	{ AddMinute(hour*PER_HOUR); }
    	void AddDay(YK_INT day)
    	{ AddHour(day*PER_DAY); }
    	void AddMonth(YK_INT month);
    	void AddYear(YK_INT year)
    	{ AddMonth(year*PER_YEAR); }
    
    	YKDateTime& operator+=(const YKDateTime& tm)
    	{ this->m_time += tm.m_time; return *this; }
    	YKDateTime& operator-=(const YKDateTime& tm)
    	{ this->m_time -= tm.m_time; return *this; }
    
    	YK_BOOL operator==(const YKDateTime& tm) const
    	{ return this->m_time == tm.m_time; }
    	YK_BOOL operator!=(const YKDateTime& tm ) const
    	{ return !(*this == tm); }
    	YK_BOOL operator>(const YKDateTime& tm ) const
    	{ return this->m_time > tm.m_time; }
    	YK_BOOL operator>=(const YKDateTime& tm ) const
    	{ return !(*this < tm); }
    	YK_BOOL operator<(const YKDateTime& tm ) const
    	{ return tm > *this ; }
    	YK_BOOL operator<=(const YKDateTime& tm ) const
    	{ return !(*this > tm); }
    
    protected:
    	YKString GetDTFormValue(DT_FORM dtf);
    
    private:
    	YK_TM	m_time;
    };
    

    实现部分:

    YK_UINT YKDateTime::PER_SECOND  = 1000;
    YK_UINT YKDateTime::PER_MINUTE = 60;
    YK_UINT YKDateTime::PER_HOUR = 60;
    YK_UINT YKDateTime::PER_DAY = 24;
    YK_UINT YKDateTime::PER_YEAR = 12;
    YKDateTime::YKDateTime( YK_TM tm /* = 0 */ )
    	: m_time(tm)
    {
    
    }
    
    YKDateTime::YKDateTime( YK_INT nYear, YK_INT nMonth, YK_INT nDay, YK_INT nHour /*= 0*/, YK_INT nMinute /*= 0*/, YK_INT nSecond /*= 0*/ )
    {
    	tm t1;
    	t1.tm_year = nYear-1900;
    	t1.tm_mon = nMonth-1;
    	t1.tm_mday = nDay;
    	t1.tm_hour = nHour;
    	t1.tm_min = nMinute;
    	t1.tm_sec = nSecond;
    
    	m_time = _mktime64(&t1);
    }
    
    YKDateTime::~YKDateTime(void)
    {
    }
    
    YKDateTime YKDateTime::GetLocalTime()
    {
    	return YKDateTime(time(NULL));
    }
    
    YK_BOOL YKDateTime::ValidDateTime()
    {
    	YKDateTime dtTemp(1900, 1, 1);
    	return m_time >= dtTemp.m_time;
    }
    
    YKDateTime YKDateTime::GetDate()
    {
    	return YKDateTime(GetYear(), GetMonth(), GetDay());
    }
    
    YK_INT YKDateTime::GetYear() const
    {
    	tm t1;
    	localtime_s(&t1, &m_time);
    	return t1.tm_year + 1900;
    }
    
    YK_INT YKDateTime::GetMonth() const
    {
    	tm t1;
    	localtime_s(&t1, &m_time);
    	return t1.tm_mon + 1;
    }
    
    YK_INT YKDateTime::GetDay() const
    {
    	tm t1;
    	localtime_s(&t1, &m_time);
    	return t1.tm_mday;
    }
    
    YK_INT YKDateTime::GetHour() const
    {
    	tm t1;
    	localtime_s(&t1, &m_time);
    	return t1.tm_hour;
    }
    
    YK_INT YKDateTime::GetMinute() const
    {
    	tm t1;
    	localtime_s(&t1, &m_time);
    	return t1.tm_min;
    }
    
    YK_INT YKDateTime::GetSecond() const
    {
    	tm t1;
    	localtime_s(&t1, &m_time);
    	return t1.tm_sec;
    }
    
    YK_INT YKDateTime::GetDayOfYear() const
    {
    	tm t1;
    	localtime_s(&t1, &m_time);
    	char temp[128];
    	strftime(temp, 128, "%j", &t1);
    	return atoi(temp);
    }
    
    YK_INT YKDateTime::GetDayOfMonth() const
    {
    	tm t1;
    	localtime_s(&t1, &m_time);
    	return t1.tm_mday;
    }
    
    YK_INT YKDateTime::GetDayOfWeek() const
    {
    	tm t1;
    	localtime_s(&t1, &m_time);
    	return t1.tm_wday == 0 ? 7 : t1.tm_wday;
    }
    
    YK_INT YKDateTime::GetWeekOfYear() const
    {
    	tm t1;
    	localtime_s(&t1, &m_time);
    	char temp[128];
    	strftime(temp, 128, "%W", &t1);
    	return atoi(temp)+1;
    }
    
    YK_INT YKDateTime::GetWeekOfMonth() const
    {
    	tm t1;
    	localtime_s(&t1, &m_time);
    	char temp[128];
    	strftime(temp, 128, "%w", &t1);
    	return atoi(temp);
    }
    
    YK_INT YKDateTime::GetFirstDayOfWeek() const
    {
    	YKDateTime dt(m_time);
    	YK_INT dayDiff = GetDayOfWeek()-1;
    	assert(dayDiff > 0);
    	dt.AddDay(-dayDiff);
    	return dt.GetDay();
    }
    
    YKString YKDateTime::Format( DT_FORM dtf /* = TF_YMDHMS1 */ )
    {
    	tm t1;
    	localtime_s(&t1, &m_time);
    	YK_WCHAR temp[128];
    	wcsftime(temp, 128, GetDTFormValue(dtf).c_str(), &t1);
    	return temp;
    }
    
    YKString YKDateTime::FormatChs( DT_FORM dtf /* = DTF_YMDHMS1 */ )
    {
    	tm t1;
    	localtime_s(&t1, &m_time);
    	YKString str;
    	YK_BOOL bDate = false;
    	switch (dtf)
    	{
    	case DTF_YMDHMS1:
    	case DTF_YMDHM1:
    	case DTF_YMD1:
    		{
    			str += YKString::Format(t1.tm_year+1900) + L"年";
    			str += YKString::FormatDigit(t1.tm_mon+1, 2) + L"月";
    			str += YKString::FormatDigit(t1.tm_mday, 2) + L"日";
    			bDate = true;
    		}
    		break;
    	}
    
    	switch (dtf)
    	{
    	case DTF_YMDHMS1:
    	case DTF_YMDHM1:
    	case DTF_HMS1:
    	case DTF_HM1:
    		{
    			if (bDate) str += L" ";
    			str += YKString::FormatDigit(t1.tm_hour, 2) + L"时";
    			str += YKString::FormatDigit(t1.tm_min, 2) + L"分";
    		}
    		break;
    
    	}
    
    	switch (dtf)
    	{
    	case DTF_YMDHMS1:
    	case DTF_HMS1:
    		{
    			str += YKString::FormatDigit(t1.tm_sec, 2) + L"秒";
    		}
    		break;
    	}
    
    	return str;
    }
    
    YKString YKDateTime::FormatPostfix(YK_WCHAR postfix)
    {
    	YKString str;
    	switch (postfix)
    	{
    	case L'S':
    		str = YKString::Format(m_time);
    		break;
    	case L'M':
    		str = YKString::Format(((YK_DOUBLE)m_time)/PER_MINUTE);
    		break;
    	case L'H':
    		str = YKString::Format(((YK_DOUBLE)m_time)/(PER_HOUR*PER_MINUTE));
    		break;
    	case L'D':
    		str = YKString::Format(((YK_DOUBLE)m_time)/(PER_DAY*PER_HOUR*PER_MINUTE));
    		break;
    	default: return str;
    	}
    
    	str += postfix;
    	return str;
    }
    
    YKDateTime YKDateTime::ParseDateTime(const YKString& str, DT_FORM tf /* = TF_YMDHMS1 */)
    {
    	switch (tf)
    	{
    	case DTF_YMDHMS1:
    		{
    			std::vector<YKString> vecDT = str.Parse<YKString>(L" ");
    			if (vecDT.size() == 2)
    			{
    				std::vector<YK_ULONG> vecDate = vecDT[0].Parse<YK_ULONG>(L"-");
    				std::vector<YK_ULONG> vecTime = vecDT[1].Parse<YK_ULONG>(L":");
    				if (vecDate.size() == 3 && vecTime.size() == 3)
    				{
    					return YKDateTime(vecDate[0], vecDate[1], vecDate[2], vecTime[0], vecTime[1], vecTime[2]);
    				}
    			}
    		}
    		break;
    	case DTF_YMDHMS2:
    		{
    			std::vector<YKString> vecDT = str.Parse<YKString>(L" ");
    			if (vecDT.size() == 2)
    			{
    				std::vector<YK_ULONG> vecDate = vecDT[0].Parse<YK_ULONG>(L"/");
    				std::vector<YK_ULONG> vecTime = vecDT[1].Parse<YK_ULONG>(L":");
    				if (vecDate.size() == 3 && vecTime.size() == 3)
    				{
    					return YKDateTime(vecDate[0], vecDate[1], vecDate[2], vecTime[0], vecTime[1], vecTime[2]);
    				}
    			}
    		}
    		break;
    	case DTF_YMDHM1:
    		{
    			std::vector<YKString> vecDT = str.Parse<YKString>(L" ");
    			if (vecDT.size() == 2)
    			{
    				std::vector<YK_ULONG> vecDate = vecDT[0].Parse<YK_ULONG>(L"-");
    				std::vector<YK_ULONG> vecTime = vecDT[1].Parse<YK_ULONG>(L":");
    				if (vecDate.size() == 3 && vecTime.size() == 2)
    				{
    					return YKDateTime(vecDate[0], vecDate[1], vecDate[2], vecTime[0], vecTime[1]);
    				}
    			}
    		}
    		break;
    	case DTF_YMDHM2:
    		{
    			std::vector<YKString> vecDT = str.Parse<YKString>(L" ");
    			if (vecDT.size() == 2)
    			{
    				std::vector<YK_ULONG> vecDate = vecDT[0].Parse<YK_ULONG>(L"/");
    				std::vector<YK_ULONG> vecTime = vecDT[1].Parse<YK_ULONG>(L":");
    				if (vecDate.size() == 3 && vecTime.size() == 2)
    				{
    					return YKDateTime(vecDate[0], vecDate[1], vecDate[2], vecTime[0], vecTime[1]);
    				}
    			}
    		}
    		break;
    	case DTF_YMD1:
    		{
    			std::vector<YK_ULONG> vecDate = str.Parse<YK_ULONG>(L"-");
    			if (vecDate.size() == 3)
    			{
    				return YKDateTime(vecDate[0], vecDate[1], vecDate[2]);
    			}
    		}
    		break;
    	case DTF_YMD2:
    		{
    			std::vector<YK_ULONG> vecDate = str.Parse<YK_ULONG>(L"/");
    			if (vecDate.size() == 3)
    			{
    				return YKDateTime(vecDate[0], vecDate[1], vecDate[2]);
    			}
    		}
    		break;
    	case DTF_HMS1:
    		{
    			std::vector<YK_ULONG> vecTime = str.Parse<YK_ULONG>(L":");
    			if (vecTime.size() == 3)
    			{
    				return YKDateTime(1970, 1, 1, vecTime[0], vecTime[1], vecTime[2]);
    			}
    		}
    		break;
    	case DTF_HM1:
    		{
    			std::vector<YK_ULONG> vecTime = str.Parse<YK_ULONG>(L":");
    			if (vecTime.size() == 2)
    			{
    				return YKDateTime(1970, 1, 1, vecTime[0], vecTime[1]);
    			}
    		}
    		break;
    	case DTF_MDYHMS1:
    		{
    			std::vector<YKString> vecDT = str.Parse<YKString>(L" ");
    			if (vecDT.size() == 2)
    			{
    				std::vector<YK_ULONG> vecDate = vecDT[0].Parse<YK_ULONG>(L"-");
    				std::vector<YK_ULONG> vecTime = vecDT[1].Parse<YK_ULONG>(L":");
    				if (vecDate.size() == 3 && vecTime.size() == 3)
    				{
    					return YKDateTime(vecDate[2], vecDate[0], vecDate[1], vecTime[0], vecTime[1], vecTime[2]);
    				}
    			}
    		}
    		break;
    	case DTF_MDYHMS2:
    		{
    			std::vector<YKString> vecDT = str.Parse<YKString>(L" ");
    			if (vecDT.size() == 2)
    			{
    				std::vector<YK_ULONG> vecDate = vecDT[0].Parse<YK_ULONG>(L"/");
    				std::vector<YK_ULONG> vecTime = vecDT[1].Parse<YK_ULONG>(L":");
    				if (vecDate.size() == 3 && vecTime.size() == 3)
    				{
    					return YKDateTime(vecDate[2], vecDate[0], vecDate[1], vecTime[0], vecTime[1], vecTime[2]);
    				}
    			}
    		}
    		break;
    	case DTF_MDYHM1:
    		{
    			std::vector<YKString> vecDT = str.Parse<YKString>(L" ");
    			if (vecDT.size() == 2)
    			{
    				std::vector<YK_ULONG> vecDate = vecDT[0].Parse<YK_ULONG>(L"-");
    				std::vector<YK_ULONG> vecTime = vecDT[1].Parse<YK_ULONG>(L":");
    				if (vecDate.size() == 3 && vecTime.size() == 2)
    				{
    					return YKDateTime(vecDate[2], vecDate[0], vecDate[1], vecTime[0], vecTime[1]);
    				}
    			}
    		}
    		break;
    	case DTF_MDYHM2:
    		{
    			std::vector<YKString> vecDT = str.Parse<YKString>(L" ");
    			if (vecDT.size() == 2)
    			{
    				std::vector<YK_ULONG> vecDate = vecDT[0].Parse<YK_ULONG>(L"/");
    				std::vector<YK_ULONG> vecTime = vecDT[1].Parse<YK_ULONG>(L":");
    				if (vecDate.size() == 3 && vecTime.size() == 2)
    				{
    					return YKDateTime(vecDate[2], vecDate[0], vecDate[1], vecTime[0], vecTime[1]);
    				}
    			}
    		}
    		break;
    	case DTF_MDY1:
    		{
    			std::vector<YK_ULONG> vecDate = str.Parse<YK_ULONG>(L"-");
    			if (vecDate.size() == 3)
    			{
    				return YKDateTime(vecDate[2], vecDate[0], vecDate[1]);
    			}
    		}
    		break;
    	case DTF_MDY2:
    		{
    			std::vector<YK_ULONG> vecDate = str.Parse<YK_ULONG>(L"/");
    			if (vecDate.size() == 3)
    			{
    				return YKDateTime(vecDate[2], vecDate[0], vecDate[1]);
    			}
    		}
    		break;
    	}
    	
    	return 0;
    }
    
    YKString YKDateTime::GetDTFormValue( DT_FORM dtf )
    {
    	YKString str;
    	switch (dtf)
    	{
    	case DTF_YMDHMS1:
    		str = L"%Y-%m-%d %H:%M:%S";
    		break;
    	case DTF_YMDHMS2:
    		str = L"%Y/%m/%d %H:%M:%S";
    		break;
    	case DTF_YMDHM1:
    		str = L"%Y-%m-%d %H:%M";
    		break;
    	case DTF_YMDHM2:
    		str = L"%Y/%m/%d %H:%M";
    		break;
    	case DTF_YMD1:
    		str = L"%Y-%m-%d";
    		break;
    	case DTF_YMD2:
    		str = L"%Y/%m/%d";
    		break;
    	case DTF_HMS1:
    		str = L"%H:%M:%S";
    		break;
    	case DTF_HM1:
    		str = L"%H:%M";
    		break;
    	case DTF_MDYHMS1:
    		str = L"%m-%d-%Y %H:%M:%S";
    		break;
    	case DTF_MDYHMS2:
    		str = L"%m/%d/%Y %H:%M:%S";
    		break;
    	case DTF_MDYHM1:
    		str = L"%m-%d-%Y %H:%M";
    		break;
    	case DTF_MDYHM2:
    		str = L"%m/%d/%Y %H:%M";
    		break;
    	case DTF_MDY1:
    		str = L"%m-%d-%Y";
    		break;
    	case DTF_MDY2:
    		str = L"%m/%d/%Y";
    		break;
    	}
    
    	return str;
    }
    
    YKDateTime YKDateTime::ParseDateTimeChs( const YKString& str, DT_FORM tf /*= DTF_YMDHMS1*/ )
    {
    	YKString::size_type fPos = 0, lPos = 0;
    	std::vector<YK_UINT> vecVal;
    	for (; lPos < str.size(); ++lPos)
    	{
    		if (str.IsAlpha(lPos))
    		{
    			YKString strTemp = str.substr(fPos, lPos-fPos);
    			strTemp.TrimLeft();
    			vecVal.push_back(strTemp.Convert<YK_UINT>());
    			fPos = lPos+1;
    		}
    	}
    
    	switch (tf)
    	{
    	case DTF_YMDHMS1:
    		return YKDateTime(vecVal[0], vecVal[1], vecVal[2], vecVal[3], vecVal[4], vecVal[5]);
    		break;
    	case DTF_YMDHM1:
    		return YKDateTime(vecVal[0], vecVal[1], vecVal[2], vecVal[3], vecVal[4]);
    		break;
    	case DTF_YMD1:
    		return YKDateTime(vecVal[0], vecVal[1], vecVal[2]);
    		break;
    	case DTF_HMS1:
    		return YKDateTime(1970, 1, 1, vecVal[0], vecVal[1], vecVal[2]);
    		break;
    	case DTF_HM1:
    		return YKDateTime(1970, 1, 1, vecVal[0], vecVal[1]);
    		break;
    	default: break;
    	}
    	return 0;
    }
    
    YK_BOOL YKDateTime::IsElapsed( YK_TM val ) const
    {
    	YKDateTime dtNow = YKDateTime::GetLocalTime();
    	return (dtNow.m_time-m_time) >= val;
    }
    
    void YKDateTime::AddMonth( YK_INT month )
    {
    	tm t1;
    	localtime_s(&t1, &m_time);
    
    	YK_INT absMonth = month;
    	if (month < 0)
    		absMonth = abs(month);
    
    	YK_INT year = absMonth / PER_YEAR;
    	YK_INT mon = absMonth % PER_YEAR;
    	if (month > 0)
    	{
    		*this = YKDateTime(t1.tm_year+1900+year, t1.tm_mon+mon, t1.tm_mday, t1.tm_hour, t1.tm_min, t1.tm_sec);
    	}
    	else
    	{
    		*this = YKDateTime(t1.tm_year+1900-year, t1.tm_mon-mon, t1.tm_mday, t1.tm_hour, t1.tm_min, t1.tm_sec);
    	}
    }


  • 相关阅读:
    PAT-字符串处理-A 1001 A+B Format (20分)
    PAT-字符串处理-B 1048 数字加密 (20分)
    数据库-第二章 关系数据库-2.3 关系的完整性
    数据库-第二章 关系数据库-2.2 关系操作
    数据库-第二章 关系数据库-2.1 关系数据结构及形式化定义
    IDLE打开Python报错 api-ms-win-crt-runtimel1-1-0.dll缺失的解决方案
    老毛桃pe安装系统
    LeetCode 213. House Robber II (动态规划)
    LeetCode 198. House Robber(DP)
    LeetCode 211. Add and Search Word
  • 原文地址:https://www.cnblogs.com/xinyuyuanm/p/2979592.html
Copyright © 2011-2022 走看看