181 lines
5.0 KiB
C++
181 lines
5.0 KiB
C++
|
#include "DateTime.h"
|
||
|
#include "BoostLog.h"
|
||
|
#include <boost/algorithm/string/split.hpp>
|
||
|
#include <boost/algorithm/string/trim.hpp>
|
||
|
#include <iomanip>
|
||
|
#include <sstream>
|
||
|
#include <time.h>
|
||
|
#ifdef __linux__
|
||
|
#include <sys/time.h>
|
||
|
#endif
|
||
|
|
||
|
DateTime::DateTime(const std::chrono::time_point<std::chrono::system_clock> &time) {
|
||
|
auto t = std::chrono::system_clock::to_time_t(time);
|
||
|
// auto tc = std::gmtime(&t);
|
||
|
auto tc = std::localtime(&t);
|
||
|
|
||
|
m_year = tc->tm_year + 1900;
|
||
|
m_month = tc->tm_mon + 1;
|
||
|
m_day = tc->tm_mday;
|
||
|
m_hour = tc->tm_hour;
|
||
|
m_minute = tc->tm_min;
|
||
|
m_second = tc->tm_sec;
|
||
|
m_week = static_cast<Week>(tc->tm_wday);
|
||
|
}
|
||
|
|
||
|
DateTime::DateTime(size_t year, size_t month, size_t day, size_t hour, size_t minute, size_t second)
|
||
|
: m_year(year), m_month(month), m_day(day), m_hour(hour), m_minute(minute), m_second(second) {
|
||
|
}
|
||
|
|
||
|
int64_t DateTime::currentMSecsSinceEpoch() {
|
||
|
#ifdef __linux__
|
||
|
timespec time;
|
||
|
|
||
|
clock_gettime(CLOCK_REALTIME, &time);
|
||
|
return time.tv_sec * 1000 + time.tv_nsec * 1e-6;
|
||
|
#else
|
||
|
return std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch()).count();
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
int64_t DateTime::currentSecsSinceEpoch() {
|
||
|
return std::chrono::duration_cast<std::chrono::seconds>(std::chrono::system_clock::now().time_since_epoch())
|
||
|
.count();
|
||
|
}
|
||
|
|
||
|
size_t DateTime::year() const {
|
||
|
return m_year;
|
||
|
}
|
||
|
|
||
|
size_t DateTime::month() const {
|
||
|
return m_month;
|
||
|
}
|
||
|
|
||
|
size_t DateTime::day() const {
|
||
|
return m_day;
|
||
|
}
|
||
|
|
||
|
DateTime::Week DateTime::week() const {
|
||
|
return m_week;
|
||
|
}
|
||
|
|
||
|
std::chrono::time_point<std::chrono::system_clock> DateTime::operator()() {
|
||
|
return makeDateTime(m_year, m_month, m_day, m_hour, m_minute, m_second);
|
||
|
}
|
||
|
|
||
|
size_t DateTime::hour() const {
|
||
|
return m_hour;
|
||
|
}
|
||
|
|
||
|
void DateTime::setHour(size_t hour) {
|
||
|
if (m_hour == hour || hour > 23) return;
|
||
|
m_hour = hour;
|
||
|
}
|
||
|
|
||
|
size_t DateTime::minute() const {
|
||
|
return m_minute;
|
||
|
}
|
||
|
|
||
|
void DateTime::setMinute(size_t minute) {
|
||
|
if (m_minute == minute || minute > 59) return;
|
||
|
m_minute = minute;
|
||
|
}
|
||
|
|
||
|
size_t DateTime::second() const {
|
||
|
return m_second;
|
||
|
}
|
||
|
|
||
|
void DateTime::setSecond(size_t second) {
|
||
|
if (m_second == second || second > 60) return;
|
||
|
m_second = second;
|
||
|
}
|
||
|
|
||
|
DateTime DateTime::currentDateTime() {
|
||
|
return DateTime(std::chrono::system_clock::now());
|
||
|
}
|
||
|
|
||
|
std::string DateTime::toString(const std::string_view &format) const {
|
||
|
auto time = makeTime(m_year, m_month, m_day, m_hour, m_minute, m_second);
|
||
|
std::ostringstream oss;
|
||
|
oss << std::put_time(std::localtime(&time), format.data());
|
||
|
return oss.str();
|
||
|
}
|
||
|
|
||
|
std::string DateTime::toString(const std::chrono::time_point<std::chrono::system_clock> &time, const std::string_view &format) {
|
||
|
|
||
|
auto now_c = std::chrono::system_clock::to_time_t(time);
|
||
|
std::ostringstream oss;
|
||
|
oss << std::put_time(std::localtime(&now_c), format.data());
|
||
|
return oss.str();
|
||
|
}
|
||
|
|
||
|
DateTime DateTime::tomorrow() {
|
||
|
DateTime ret(*this);
|
||
|
size_t currentMonthDays = days(ret.m_year, ret.m_month);
|
||
|
ret.m_day++;
|
||
|
if (ret.m_day <= currentMonthDays) return ret;
|
||
|
ret.m_day = 1;
|
||
|
ret.m_month++;
|
||
|
if (m_month <= 12) return ret;
|
||
|
ret.m_month = 1;
|
||
|
ret.m_year++;
|
||
|
return ret;
|
||
|
}
|
||
|
|
||
|
bool DateTime::isLeapYear(size_t year) {
|
||
|
return ((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0);
|
||
|
}
|
||
|
|
||
|
size_t DateTime::days(size_t year, size_t month) {
|
||
|
switch (month) {
|
||
|
case 1:
|
||
|
case 3:
|
||
|
case 5:
|
||
|
case 7:
|
||
|
case 8:
|
||
|
case 10:
|
||
|
case 12:
|
||
|
return 31;
|
||
|
case 4:
|
||
|
case 6:
|
||
|
case 9:
|
||
|
case 11:
|
||
|
return 30;
|
||
|
case 2:
|
||
|
return isLeapYear(year) ? 29 : 28;
|
||
|
default:
|
||
|
return -1;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
std::chrono::time_point<std::chrono::system_clock> DateTime::makeDateTime(size_t year, size_t month, size_t day, size_t hour, size_t minute,
|
||
|
size_t second) {
|
||
|
return std::chrono::system_clock::from_time_t(makeTime(year, month, day, hour, minute, second));
|
||
|
}
|
||
|
|
||
|
std::time_t DateTime::makeTime(size_t year, size_t month, size_t day, size_t hour, size_t minute, size_t second) {
|
||
|
time_t rawtime;
|
||
|
time(&rawtime);
|
||
|
auto timepoint = localtime(&rawtime);
|
||
|
timepoint->tm_year = static_cast<int>(year - 1900);
|
||
|
timepoint->tm_mon = static_cast<int>(month - 1);
|
||
|
timepoint->tm_mday = static_cast<int>(day);
|
||
|
timepoint->tm_hour = static_cast<int>(hour);
|
||
|
timepoint->tm_min = static_cast<int>(minute);
|
||
|
timepoint->tm_sec = static_cast<int>(second);
|
||
|
|
||
|
return std::mktime(timepoint);
|
||
|
}
|
||
|
|
||
|
std::tuple<uint8_t, uint8_t, uint8_t> DateTime::parseTime(const std::string &text) {
|
||
|
auto timeStr = boost::algorithm::trim_copy(text);
|
||
|
std::vector<std::string> result;
|
||
|
boost::algorithm::split(result, timeStr, boost::algorithm::is_any_of(":"));
|
||
|
if (result.size() > 3 || result.size() < 2) return {(uint8_t)-1, (uint8_t)-1, (uint8_t)-1};
|
||
|
|
||
|
auto hour = std::stoi(result.at(0));
|
||
|
auto minute = std::stoi(result.at(1));
|
||
|
auto second = result.size() > 2 ? std::stoi(result.at(2)) : 0;
|
||
|
return std::make_tuple(hour, minute, second);
|
||
|
}
|