#include "LeeDateTime.h"
#include <sstream>
#include <cmath>
const double CLeeDateTimeSpan::THREE_MILLISECOND = 3 / 1000.0 / 3600.0 / 24.0;const double CLeeDateTime::HALF_SECOND = 0.5 / 3600.0 / 24.0;const double CLeeDateTime::THREE_MILLISECOND = 3 / 1000.0 / 3600.0 / 24.0;
CLeeDateTime::CLeeDateTime(const struct tm& _tm)
{
int time_zone = CLeeDateTime::GetTimeZone();
if (_tm.tm_year < 70 ||
(_tm.tm_year == 70 && _tm.tm_mon == 0 && _tm.tm_mday == 1 && _tm.tm_hour < time_zone)) {
const static int DaysOfMonth[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
if (_tm.tm_mon < 0 || _tm.tm_mon > 11) {
*this = CLeeDateTime();
return;
}
int day_num_of_year = 0;
for (int i = 0; i < 12; ++i) {
if (i < _tm.tm_mon) {
day_num_of_year += DaysOfMonth[i];
if (i == 1 && CLeeDateTime::IsLeapYear(_tm.tm_year + 1900)) {
day_num_of_year += 1; }
}
else if (i == _tm.tm_mon) {
day_num_of_year += _tm.tm_mday - 1;
break;
}
}
int rest_day_num_of_this_year_to_1970 = 0;
for (int _year = _tm.tm_year + 1900; _year < 1970; ++_year)
{
if (CLeeDateTime::IsLeapYear(_year))
{
rest_day_num_of_this_year_to_1970 += 366; }
else
{
rest_day_num_of_this_year_to_1970 += 365; }
}
time_t total_second_num = rest_day_num_of_this_year_to_1970 * 24LL * 60LL * 60LL
- day_num_of_year * 24LL * 60LL * 60LL
- _tm.tm_hour * 60LL * 60LL
- _tm.tm_min * 60LL
- _tm.tm_sec
; *this = CLeeDateTime(- total_second_num - static_cast<time_t>(time_zone * (60LL * 60LL))); }
else
{
struct tm* tm_ptr = const_cast<struct tm*>(&_tm);
#ifdef _WIN32
const time_t t = ::_mkgmtime(tm_ptr)
#else
const time_t t = ::timegm(tm_ptr)
#endif
- static_cast<time_t>(time_zone) * 60LL * 60LL;
*this = CLeeDateTime(t);
}
}
CLeeDateTime::CLeeDateTime(int year, int month, int day,
int hour , int minute , int second , int millisecond )
#ifdef _WIN32
: CLeeDateTime(::SYSTEMTIME{
static_cast<WORD>(year), static_cast<WORD>(month), 0, static_cast<WORD>(day),
static_cast<WORD>(hour), static_cast<WORD>(minute), static_cast<WORD>(second),
static_cast<WORD>(millisecond) })
#endif
{
#if defined(__linux__) || defined(__APPLE__)
struct tm _tm = { 0 };
_tm.tm_year = year - 1900;
_tm.tm_mon = month - 1;
_tm.tm_mday = day;
_tm.tm_hour = hour;
_tm.tm_min = minute;
_tm.tm_sec = second;
*this = CLeeDateTime(_tm) + CLeeDateTimeSpan(0, 0, 0, 0, millisecond);
#endif
}
#ifdef _WIN32
CLeeDateTime::CLeeDateTime(const ::SYSTEMTIME& st)
{
FILETIME fileTime1 = { 0 }; ::SystemTimeToFileTime(&st, &fileTime1);
long long ll = 0;
::memcpy(&ll, &fileTime1, sizeof(::FILETIME));
m_dt = ll / (10.0 * 1000.0 * 1000.0 * 60.0 * 60.0 * 24.0) - 109205.0;}
#endif
#if defined(__linux__) || defined(__APPLE__)
CLeeDateTime::CLeeDateTime(const timeval& st)
{
*this = CLeeDateTime(st.tv_sec) + CLeeDateTimeSpan(0, 0, 0, 0, static_cast<int>(st.tv_usec) / 1000);
}
#endif
CLeeDateTime::CLeeDateTime(const string& str)
{
ParseDateTime(str);
}
string CLeeDateTime::Format(const string& format ) const
{
struct tm newtime = Get_tm();
char tmpbuf[128] = { 0 };
strftime(tmpbuf, 128, format.c_str(), &newtime);
return string(tmpbuf);
}
string CLeeDateTime::FormatWithMillisecond(const string& format ) const
{
#ifdef _WIN32
long long ll = static_cast<long long>((m_dt + 109205.0)
* 24.0 * 3600.0 * 1000.0 * 1000.0 * 10.0);
::FILETIME fileTime1 = { 0 };
::memcpy(&fileTime1, &ll, sizeof(::FILETIME));
::SYSTEMTIME sysTime1 = { 0 };
::FileTimeToSystemTime(&fileTime1, &sysTime1);
struct tm newtime {
static_cast<int>(sysTime1.wSecond),
static_cast<int>(sysTime1.wMinute),
static_cast<int>(sysTime1.wHour),
static_cast<int>(sysTime1.wDay),
static_cast<int>(sysTime1.wMonth - 1),
static_cast<int>(sysTime1.wYear - 1900),
static_cast<int>(sysTime1.wDayOfWeek),
0,
0
}; char tmpbuf[128] = { 0 };
::strftime(tmpbuf, 128, format.c_str(), &newtime);
char millisecond_buf[5] = { 0 };
::sprintf(millisecond_buf, ".%03u", sysTime1.wMilliseconds);
return string(tmpbuf) + millisecond_buf;
#endif
#if defined(__linux__) || defined(__APPLE__)
timeval tv = Get_timeval();
time_t t = tv.tv_sec + CLeeDateTime::GetTimeZone() * (60LL * 60LL);
struct tm _tm = { 0 };
::gmtime_r(&t, &_tm);
char tmpbuf[128] = { 0 };
::strftime(tmpbuf, 128, format.c_str(), &_tm);
char millisecond_buf[5] = { 0 };
::sprintf(millisecond_buf, ".%03ld", tv.tv_usec / 1000);
return string(tmpbuf) + millisecond_buf;
#endif
}
void CLeeDateTime::SetDateTime(int year, int month, int day, int hour , int minute ,
int second , int millisecond )
{
*this = CLeeDateTime(year, month, day, hour, minute, second, millisecond);
}
void CLeeDateTime::SetMiddleNight()
{
m_dt = floor(m_dt);
}
void CLeeDateTime::ParseDateTime(const string& str)
{
std::istringstream iss(str);
char symbol = 0; int wYear(0), wMonth(0), wDay(0), wHour(0), wMinute(0), wSecond(0), wMilliseconds(0);
iss >> wYear >> symbol; if (symbol == ':') { wYear = 1899;
wMonth = 12;
wDay = 30;
iss.clear();
iss.str(str);
iss >> wHour >> symbol
>> wMinute >> symbol
>> wSecond >> symbol
>> wMilliseconds;
}
else {
iss >> wMonth >> symbol
>> wDay
>> wHour >> symbol
>> wMinute >> symbol
>> wSecond >> symbol
>> wMilliseconds;
}
*this = CLeeDateTime(wYear, wMonth, wDay, wHour, wMinute, wSecond, wMilliseconds);
}
int CLeeDateTime::GetYear() const
{
#ifdef _WIN32
return Get_SYSTEMTIME().wYear;
#endif
#if defined(__linux__) || defined(__APPLE__)
double raw_time_t = (m_dt - 25569) * (24.0 * 60.0 * 60.0);
time_t t = static_cast<time_t>(floor(raw_time_t));
struct tm _tm = { 0 };
::gmtime_r(&t, &_tm);
return _tm.tm_year + 1900;
#endif
}
int CLeeDateTime::GetMonth() const
{
#ifdef _WIN32
return Get_SYSTEMTIME().wMonth;
#endif
#if defined(__linux__) || defined(__APPLE__)
double raw_time_t = (m_dt - 25569) * (24.0 * 60.0 * 60.0);
time_t t = static_cast<time_t>(floor(raw_time_t));
struct tm _tm = { 0 };
::gmtime_r(&t, &_tm);
return _tm.tm_mon + 1;
#endif
}
int CLeeDateTime::GetDay() const
{
#ifdef _WIN32
return Get_SYSTEMTIME().wDay;
#endif
#if defined(__linux__) || defined(__APPLE__)
double raw_time_t = (m_dt - 25569) * (24.0 * 60.0 * 60.0);
time_t t = static_cast<time_t>(floor(raw_time_t));
struct tm _tm = { 0 };
::gmtime_r(&t, &_tm);
return _tm.tm_mday;
#endif
}
int CLeeDateTime::GetHour() const
{
#ifdef _WIN32
return Get_SYSTEMTIME().wHour;
#endif
#if defined(__linux__) || defined(__APPLE__)
double raw_time_t = (m_dt - 25569) * (24.0 * 60.0 * 60.0);
time_t t = static_cast<time_t>(floor(raw_time_t));
struct tm _tm = { 0 };
::gmtime_r(&t, &_tm);
return _tm.tm_hour;
#endif
}
int CLeeDateTime::GetMinute() const
{
#ifdef _WIN32
return Get_SYSTEMTIME().wMinute;
#endif
#if defined(__linux__) || defined(__APPLE__)
double raw_time_t = (m_dt - 25569) * (24.0 * 60.0 * 60.0);
time_t t = static_cast<time_t>(floor(raw_time_t));
struct tm _tm = { 0 };
::gmtime_r(&t, &_tm);
return _tm.tm_min;
#endif
}
int CLeeDateTime::GetSecond() const
{
#ifdef _WIN32
return Get_SYSTEMTIME().wSecond;
#endif
#if defined(__linux__) || defined(__APPLE__)
double raw_time_t = (m_dt - 25569) * (24.0 * 60.0 * 60.0);
time_t t = static_cast<time_t>(floor(raw_time_t));
struct tm _tm = { 0 };
::gmtime_r(&t, &_tm);
return _tm.tm_sec;
#endif
}
int CLeeDateTime::GetMillisecond() const
{
#ifdef _WIN32
return Get_SYSTEMTIME().wMilliseconds;
#endif
#if defined(__linux__) || defined(__APPLE__)
return static_cast<int>(Get_timeval().tv_usec) / 1000;
#endif
}
int CLeeDateTime::GetDayOfWeek() const
{
#ifdef _WIN32
return Get_SYSTEMTIME().wDayOfWeek;
#endif
#if defined(__linux__) || defined(__APPLE__)
double raw_time_t = (m_dt - 25569) * (24.0 * 60.0 * 60.0);
time_t t = static_cast<time_t>(floor(raw_time_t));
struct tm _tm = { 0 };
::gmtime_r(&t, &_tm);
return _tm.tm_wday;
#endif
}
#ifdef _WIN32
::SYSTEMTIME CLeeDateTime::Get_SYSTEMTIME() const
{
long long ll = static_cast<long long>((m_dt + 109205.0)
* 24.0 * 60.0 * 60.0 * 1000.0 * 1000.0 * 10.0); ::FILETIME fileTime1 = { 0 };
::memcpy(&fileTime1, &ll, sizeof(::FILETIME));
::SYSTEMTIME sysTime1 = { 0 };
::FileTimeToSystemTime(&fileTime1, &sysTime1);
return sysTime1;
}
#endif
#if defined(__linux__) || defined(__APPLE__)
::timeval CLeeDateTime::Get_timeval() const {
::timeval tv = { 0 };
double raw_second_num = (m_dt - 25569) * (24.0 * 60.0 * 60.0)
- CLeeDateTime::GetTimeZone() * (60.0 * 60.0);
tv.tv_sec = static_cast<time_t>(floor(raw_second_num));
tv.tv_usec = static_cast<suseconds_t>((raw_second_num - static_cast<double>(tv.tv_sec)) * 1000000);
return tv;
}
#endif
struct tm CLeeDateTime::Get_tm() const
{
#ifdef _WIN32
::SYSTEMTIME sysTime1 =
CLeeDateTime(m_dt + HALF_SECOND).Get_SYSTEMTIME(); struct tm newtime { static_cast<int>(sysTime1.wSecond),
static_cast<int>(sysTime1.wMinute),
static_cast<int>(sysTime1.wHour),
static_cast<int>(sysTime1.wDay),
static_cast<int>(sysTime1.wMonth - 1),
static_cast<int>(sysTime1.wYear - 1900),
static_cast<int>(sysTime1.wDayOfWeek),
0,
0 };
return newtime;
#endif
#if defined(__linux__) || defined(__APPLE__)
time_t t = Get_time_t() + CLeeDateTime::GetTimeZone() * (60LL * 60LL);
struct tm _tm = { 0 };
::gmtime_r(&t, &_tm);
return _tm;
#endif
}
struct tm CLeeDateTime::Get_GMT_tm() const
{
#ifdef _WIN32
::SYSTEMTIME sysTime1 =
CLeeDateTime(m_dt - CLeeDateTime::GetTimeZone() / 24.0 + HALF_SECOND).Get_SYSTEMTIME(); struct tm newtime {
static_cast<int>(sysTime1.wSecond),
static_cast<int>(sysTime1.wMinute),
static_cast<int>(sysTime1.wHour),
static_cast<int>(sysTime1.wDay),
static_cast<int>(sysTime1.wMonth - 1),
static_cast<int>(sysTime1.wYear - 1900),
static_cast<int>(sysTime1.wDayOfWeek),
0,
0
};
return newtime;
#endif
#if defined(__linux__) || defined(__APPLE__)
time_t t = Get_time_t();
struct tm _tm = { 0 };
::gmtime_r(&t, &_tm);
return _tm;
#endif
}
time_t CLeeDateTime::Get_time_t() const
{
return CLeeDateTime::double_to_time_t(m_dt);
}
CLeeDateTime CLeeDateTime::operator+(const CLeeDateTimeSpan& span) const
{
return CLeeDateTime(m_dt + span.m_span);
}
CLeeDateTime& CLeeDateTime::operator+=(const CLeeDateTimeSpan& span)
{
m_dt += span.m_span;
return *this;
}
CLeeDateTime CLeeDateTime::operator-(const CLeeDateTimeSpan& span) const
{
return CLeeDateTime(m_dt - span.m_span);
}
CLeeDateTime& CLeeDateTime::operator-=(const CLeeDateTimeSpan& span)
{
m_dt -= span.m_span;
return *this;
}
CLeeDateTimeSpan CLeeDateTime::operator-(const CLeeDateTime& rhs) const
{
return CLeeDateTimeSpan(m_dt - rhs.m_dt);
}
CLeeDateTime CLeeDateTime::GetCurrentTime(){
#ifdef _WIN32
::SYSTEMTIME sysTime1 = { 0 };
::GetSystemTime(&sysTime1);
return CLeeDateTime(sysTime1) + CLeeDateTimeSpan(0, CLeeDateTime::GetTimeZone(), 0, 0);
#endif
#if defined(__linux__) || defined(__APPLE__)
::timeval tv;
::gettimeofday(&tv, nullptr);
return CLeeDateTime(tv);
#endif
}
int CLeeDateTime::GetTimeZone() {
return 8;
}
bool CLeeDateTime::IsLeapYear(int year)
{
return (year % 4 == 0 && ((year % 400 == 0) || (year % 100 != 0)));
}
int CLeeDateTime::GetDays(int year, int month)
{
int nDays = 0;
switch (month)
{
case 1:
case 3:
case 5:
case 7:
case 8:
case 10:
case 12:
nDays = 31;
break;
case 2:
nDays = IsLeapYear(year) ? 29 : 28;
break;
case 4:
case 6:
case 9:
case 11:
nDays = 30;
break;
default:
break;
}
return nDays;
}
bool CLeeDateTime::IsLeapYear() const
{
int year = GetYear();
return CLeeDateTime::IsLeapYear(year);
}
CLeeDateTime& CLeeDateTime::operator=(const CLeeDateTime& rhs)
{
if (this == &rhs) {
return *this;
}
m_dt = rhs.m_dt;
return *this;
}
bool CLeeDateTime::operator>(const CLeeDateTime& rhs) const
{
return m_dt - rhs.m_dt >= CLeeDateTime::THREE_MILLISECOND;
}
bool CLeeDateTime::operator<(const CLeeDateTime& rhs) const
{
return rhs.m_dt - m_dt >= CLeeDateTime::THREE_MILLISECOND;
}
bool CLeeDateTime::operator>=(const CLeeDateTime& rhs) const
{
return !(*this < rhs);
}
bool CLeeDateTime::operator<=(const CLeeDateTime& rhs) const
{
return !(*this > rhs);
}
bool CLeeDateTime::operator==(const CLeeDateTime& rhs) const
{
return m_dt - rhs.m_dt < CLeeDateTime::THREE_MILLISECOND &&
rhs.m_dt - m_dt < CLeeDateTime::THREE_MILLISECOND;
}
bool CLeeDateTime::operator!=(const CLeeDateTime& rhs) const
{
return !(*this == rhs);
}
double CLeeDateTime::time_t_to_double(time_t t) {
return static_cast<double>(t) / (24.0 * 60.0 * 60.0) + 25569.0 + CLeeDateTime::GetTimeZone() / 24.0;}
time_t CLeeDateTime::double_to_time_t(double d) {
return static_cast<time_t>(floor((d - 25569) * (24.0 * 60.0 * 60.0)
- CLeeDateTime::GetTimeZone() * (60.0 * 60.0) + 0.5));}