ソフトウェアアーキテクチャ設計の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);
}
}