C++ 简易时间类
.h file
#ifndef LIBFRAME_DATETIME_H_ #define LIBFRAME_DATETIME_H_ #include <stdint.h> #include "platform/platform.h"class CDateTime { public: struct Time { int16_t year, month, day, hour, minite, second, milliseconds, dayOfWeek; }; enum { enmDateTime_MsPerSec = 1000, enmDateTime_SecPerMin = 60, enmDateTime_MinPerHour = 60, enmDateTime_SecPerHour = enmDateTime_SecPerMin * enmDateTime_MinPerHour, enmDateTime_HourPerDay = 24, enmDateTime_SecPerDay = enmDateTime_SecPerHour * enmDateTime_HourPerDay, enmDateTime_DayPerWeek = 7, enmDateTime_SecPerWeek = enmDateTime_SecPerDay * enmDateTime_DayPerWeek, }; enum { // 2017-1-1 0:0:0 enmDateTimeToStr__yyyy_MM_dd_hh_mm_ss = 0, // 2017-1-1 0:0:0:0 enmDateTimeToStr__yyyy_MM_dd_hh_mm_ss_ms = 1, // 2017-1-1 0:0:0 6 enmDateTimeToStr__yyyy_MM_dd_hh_mm_ss_wday = 2, // 2017-1-1 0:0:0:0 6 enmDateTimeToStr__yyyy_MM_dd_hh_mm_ss_ms_wday = 3, }; public: CDateTime(uint16_t year = 0, uint16_t month = 0, uint16_t day = 0, uint16_t hour = 0, uint16_t minite = 0, uint16_t second = 0, uint16_t millisecond = 0); CDateTime(int64_t seconds); ~CDateTime(); static CDateTime CurrentLocalTime(); static CDateTime CurrentSystemTime(); static bool IsLeapYear(int16_t year); static int16_t GetMonthDays(int16_t year, int16_t month); const CDateTime::Time &GetTime() const; int64_t Seconds() const; int64_t MilliSeconds() const; int32_t ToString(char buf[], int32_t maxBufLen, int32_t format = enmDateTimeToStr__yyyy_MM_dd_hh_mm_ss); CDateTime DayBeginTime() const; CDateTime WeekBeginTime() const; CDateTime MonthBeginTime() const; CDateTime LastMonthBeginTime() const; CDateTime NextMonthBeginTime() const; CDateTime YearBeginTime() const; bool InSameMonth(int64_t timestamp, int32_t offset = 0); bool InSameWeek(int64_t timestamp, int32_t offset = 0); bool InSameDay(int64_t timestamp, int32_t offset = 0); private: void FetchLoaclTime(); void FetchSystemTime(); void SetTime(const CDateTime::Time &time); void SetSeconds(int64_t seconds); void SetMilliSeconds(int64_t milliseconds); int64_t MakeTime(uint16_t year = 0, uint16_t month = 0, uint16_t day = 0, uint16_t hour = 0, uint16_t minite = 0, uint16_t second = 0); private: Time m_time; int64_t m_seconds; // seconds int64_t m_milliseconds; // milliseconds }; #endif
.cpp file
#include <ctime> #include "datetime.h" CDateTime::CDateTime(uint16_t year /*= 0*/, uint16_t month /*= 0*/, uint16_t day /*= 0*/, uint16_t hour /*= 0*/, uint16_t minite /*= 0*/, uint16_t second /*= 0*/, uint16_t millisecond /*= 0*/) { m_time.year = year; m_time.month = month; m_time.day = day; m_time.hour = hour; m_time.minite = minite; m_time.second = second; m_time.milliseconds = millisecond; m_seconds = MakeTime(m_time.year, m_time.month, m_time.day, m_time.hour, m_time.minite, m_time.second); struct tm *ptm = localtime(&m_seconds); m_time.dayOfWeek = ptm->tm_wday; m_milliseconds = m_seconds * enmDateTime_MsPerSec + m_time.milliseconds; } CDateTime::CDateTime(int64_t seconds) { struct tm *ptm = localtime(&seconds); m_time.year = ptm->tm_year + 1900; m_time.month = ptm->tm_mon + 1; m_time.day = ptm->tm_mday; m_time.hour = ptm->tm_hour; m_time.minite = ptm->tm_min; m_time.second = ptm->tm_sec; m_time.milliseconds = 0; m_time.dayOfWeek = ptm->tm_wday; m_seconds = seconds; m_milliseconds = m_seconds * enmDateTime_MsPerSec + m_time.milliseconds; } CDateTime::~CDateTime() { } CDateTime CDateTime::CurrentLocalTime() { static CDateTime localTime; localTime.FetchLoaclTime(); return localTime; } CDateTime CDateTime::CurrentSystemTime() { static CDateTime systemTime; systemTime.FetchSystemTime(); return systemTime; } bool CDateTime::IsLeapYear(int16_t year) { return (year % 400 == 0) || (year % 100 != 0 && year % 4 == 0); } int16_t CDateTime::GetMonthDays(int16_t year, int16_t month) { static int16_t common_year_month_days[] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; static int16_t leap_year_month_days[] = { 0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; if (month < 1 || month > 12) { month = 0; } if (IsLeapYear(year)) { return leap_year_month_days[month]; } else { return common_year_month_days[month]; } } int64_t CDateTime::MakeTime(uint16_t year /*= 0*/, uint16_t month /*= 0*/, uint16_t day /*= 0*/, uint16_t hour /*= 0*/, uint16_t minite /*= 0*/, uint16_t second /*= 0*/) { struct tm st = { 0 }; if (year < 1970) { year = 1970; } st.tm_year = year - 1900; st.tm_mon = month - 1; st.tm_mday = day; st.tm_hour = hour; st.tm_min = minite; st.tm_sec = second; int64_t seconds = mktime(&st); if (seconds < 0) { seconds = 0; } return seconds; } void CDateTime::FetchLoaclTime() { #ifdef OS_WINDOWS static SYSTEMTIME sysTime; GetLocalTime(&sysTime); m_time.year = sysTime.wYear; m_time.month = sysTime.wMonth; m_time.day = sysTime.wDay; m_time.hour = sysTime.wHour; m_time.minite = sysTime.wMinute; m_time.second = sysTime.wSecond; m_time.milliseconds = sysTime.wMilliseconds; m_time.dayOfWeek = sysTime.wDayOfWeek; m_seconds = MakeTime(m_time.year, m_time.month, m_time.day, m_time.hour, m_time.minite, m_time.second); m_milliseconds = m_seconds * enmDateTime_MsPerSec + m_time.milliseconds; #endif // OS_WINDOWS #ifdef OS_LINUX static struct timeb tp; ftime(&tp); struct tm *ptm = localtime(&tp.time); m_time.year = ptm->tm_year + 1900; m_time.month = ptm->tm_mon + 1; m_time.day = ptm->tm_mday; m_time.hour = ptm->tm_hour; m_time.minite = ptm->tm_min; m_time.second = ptm->tm_sec; m_time.milliseconds = tp.millitm; m_time.dayOfWeek = ptm->tm_wday; m_seconds = tp.time; m_milliseconds = m_seconds * enmDateTime_MsPerSec + m_time.milliseconds; #endif // OS_LINUX } void CDateTime::FetchSystemTime() { #ifdef OS_WINDOWS static SYSTEMTIME sysTime; GetSystemTime(&sysTime); m_time.year = sysTime.wYear; m_time.month = sysTime.wMonth; m_time.day = sysTime.wDay; m_time.hour = sysTime.wHour; m_time.minite = sysTime.wMinute; m_time.second = sysTime.wSecond; m_time.milliseconds = sysTime.wMilliseconds; m_time.dayOfWeek = sysTime.wDayOfWeek; m_seconds = MakeTime(m_time.year, m_time.month, m_time.day, m_time.hour, m_time.minite, m_time.second); m_milliseconds = m_seconds * enmDateTime_MsPerSec + m_time.milliseconds; #endif // OS_WINDOWS #ifdef OS_LINUX static struct timeb tp; ftime(&tp); struct tm *ptm = gmtime(&tp.time); m_time.year = ptm->tm_year + 1900; m_time.month = ptm->tm_mon + 1; m_time.day = ptm->tm_mday; m_time.hour = ptm->tm_hour; m_time.minite = ptm->tm_min; m_time.second = ptm->tm_sec; m_time.milliseconds = tp.millitm; m_time.dayOfWeek = ptm->tm_wday; m_seconds = tp.time; m_milliseconds = m_seconds * enmDateTime_MsPerSec + m_time.milliseconds; #endif // OS_LINUX } void CDateTime::SetTime(const CDateTime::Time &time) { m_time = time; } void CDateTime::SetSeconds(int64_t seconds) { m_seconds = seconds; } void CDateTime::SetMilliSeconds(int64_t milliseconds) { m_milliseconds = milliseconds; } const CDateTime::Time & CDateTime::GetTime() const { return m_time; } int64_t CDateTime::Seconds() const { return m_seconds; } int64_t CDateTime::MilliSeconds() const { return m_milliseconds; } int32_t CDateTime::ToString(char buf[], int32_t maxBufLen, int32_t format /*= enmDateTimeToStr__yyyy_MM_dd_hh_mm_ss*/) { const CDateTime::Time &time = GetTime(); switch (format) { case enmDateTimeToStr__yyyy_MM_dd_hh_mm_ss: return sprintf(buf, maxBufLen, "%04d-%02d-%02d %02d:%02d:%02d", time.year, time.month, time.day, time.hour, time.minite, time.second); case enmDateTimeToStr__yyyy_MM_dd_hh_mm_ss_ms: return sprintf(buf, maxBufLen, "%04d-%02d-%02d %02d:%02d:%02d:%03d", time.year, time.month, time.day, time.hour, time.minite, time.second, time.milliseconds); case enmDateTimeToStr__yyyy_MM_dd_hh_mm_ss_wday: return sprintf(buf, maxBufLen, "%04d-%02d-%02d %02d:%02d:%02d %d", time.year, time.month, time.day, time.hour, time.minite, time.second, time.dayOfWeek); case enmDateTimeToStr__yyyy_MM_dd_hh_mm_ss_ms_wday: return sprintf(buf, maxBufLen, "%04d-%02d-%02d %02d:%02d:%02d:%03d %d", time.year, time.month, time.day, time.hour, time.minite, time.second, time.milliseconds, time.dayOfWeek); default: return sprintf(buf, maxBufLen, "%04d-%02d-%02d %02d:%02d:%02d", time.year, time.month, time.day, time.hour, time.minite, time.second); } } CDateTime CDateTime::DayBeginTime() const { CDateTime dayBeginTime; Time time = GetTime(); time.hour = 0; time.minite = 0; time.second = 0; time.milliseconds = 0; dayBeginTime.SetTime(time); dayBeginTime.SetSeconds(m_seconds - GetTime().hour * enmDateTime_SecPerHour - GetTime().minite * enmDateTime_SecPerMin - GetTime().second); dayBeginTime.SetMilliSeconds(dayBeginTime.Seconds() * enmDateTime_MsPerSec); return dayBeginTime; } CDateTime CDateTime::WeekBeginTime() const { CDateTime weekBeginTime; Time time = GetTime(); time.dayOfWeek = 1; time.day -= (GetTime().dayOfWeek - 1); time.hour = 0; time.minite = 0; time.second = 0; time.milliseconds = 0; weekBeginTime.SetTime(time); weekBeginTime.SetSeconds(m_seconds - (GetTime().dayOfWeek - 1) * enmDateTime_SecPerDay - GetTime().hour * enmDateTime_SecPerHour - GetTime().minite * enmDateTime_SecPerMin - GetTime().second); weekBeginTime.SetMilliSeconds(weekBeginTime.Seconds() * enmDateTime_MsPerSec); return weekBeginTime; } CDateTime CDateTime::MonthBeginTime() const { CDateTime monthBeginTime; Time time = GetTime(); int16_t wdayOffset = (GetTime().day - 1) % enmDateTime_DayPerWeek; time.dayOfWeek = time.dayOfWeek > wdayOffset ? time.dayOfWeek - wdayOffset : time.dayOfWeek + enmDateTime_DayPerWeek - wdayOffset; time.day -= (GetTime().day - 1); time.hour = 0; time.minite = 0; time.second = 0; time.milliseconds = 0; monthBeginTime.SetTime(time); monthBeginTime.SetSeconds(m_seconds - (GetTime().day - 1) * enmDateTime_SecPerDay - GetTime().hour * enmDateTime_SecPerMin * enmDateTime_MinPerHour - GetTime().minite * enmDateTime_SecPerMin - GetTime().second); monthBeginTime.SetMilliSeconds(monthBeginTime.Seconds() * enmDateTime_MsPerSec); return monthBeginTime; } LibFrame::CDateTime CDateTime::LastMonthBeginTime() const { return CDateTime(MonthBeginTime().Seconds() - 1).MonthBeginTime(); } LibFrame::CDateTime CDateTime::NextMonthBeginTime() const { return CDateTime(MonthBeginTime().Seconds() + GetMonthDays(GetTime().year, GetTime().month) * enmDateTime_SecPerDay + 1).MonthBeginTime(); } LibFrame::CDateTime CDateTime::YearBeginTime() const { return CDateTime(GetTime().year, 1, 1); } bool CDateTime::InSameMonth(int64_t timestamp, int32_t offset /*= 0*/) { int64_t thisMonthDemarcationPoint = MonthBeginTime().Seconds() + offset; return (timestamp < thisMonthDemarcationPoint + offset && thisMonthDemarcationPoint + offset < Seconds()) || (timestamp < LastMonthBeginTime().Seconds() + offset) || (timestamp > NextMonthBeginTime().Seconds() + offset); } bool CDateTime::InSameWeek(int64_t timestamp, int32_t offset /*= 0*/) { int64_t thisWeekDemarcationPoint = WeekBeginTime().Seconds() + offset; return (timestamp < thisWeekDemarcationPoint && thisWeekDemarcationPoint < Seconds()) || (timestamp < thisWeekDemarcationPoint - enmDateTime_SecPerWeek) || (timestamp > thisWeekDemarcationPoint + enmDateTime_SecPerWeek); } bool CDateTime::InSameDay(int64_t timestamp, int32_t offset /*= 0*/) { int64_t todayDemarcationPoint = Seconds() + offset; return (timestamp < todayDemarcationPoint && todayDemarcationPoint < Seconds()) || (timestamp < todayDemarcationPoint - enmDateTime_SecPerDay) || (timestamp > todayDemarcationPoint + enmDateTime_SecPerDay); }