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);
}

原文地址:https://www.cnblogs.com/tangxin-blog/p/4720869.html