This commit is contained in:
UnknownObject
2026-06-30 17:49:51 +08:00
commit 292c09619e
200 changed files with 23718 additions and 0 deletions
+505
View File
@@ -0,0 +1,505 @@
#include "DateTime.h"
#include <chrono>
#include <format>
#include <stdexcept>
void DateTime::UpdateDT()
{
namespace ch = std::chrono;
auto tp = ch::system_clock::from_time_t(storage);
try
{
// C++20 时区感知:将系统时间转换为本地时间
auto local_tp = ch::current_zone()->to_local(tp);
auto dp = ch::floor<ch::days>(local_tp);
ch::year_month_day ymd { dp };
ch::hh_mm_ss hms { local_tp - dp };
sep_time.year = static_cast<int>(ymd.year());
sep_time.month = static_cast<unsigned>(ymd.month());
sep_time.day = static_cast<unsigned>(ymd.day());
sep_time.hour = hms.hours().count();
sep_time.minute = hms.minutes().count();
sep_time.second = static_cast<int>(hms.seconds().count());
}
catch (...)
{
// 备用方案:如果系统未配置或不支持本地时区数据库,平滑降级到传统安全实现
std::tm ptm {};
#ifdef _WIN32
localtime_s(&ptm, &storage);
#else
localtime_r(&storage, &ptm);
#endif
sep_time.year = ptm.tm_year + 1900;
sep_time.month = ptm.tm_mon + 1;
sep_time.day = ptm.tm_mday;
sep_time.hour = ptm.tm_hour;
sep_time.minute = ptm.tm_min;
sep_time.second = ptm.tm_sec;
}
}
time_t DateTime::FormatConvert(int year, int month, int day, int hour, int minute, int second)
{
namespace ch = std::chrono;
try
{
ch::year_month_day ymd { ch::year{year}, ch::month{static_cast<unsigned>(month)}, ch::day{static_cast<unsigned>(day)} };
if (!ymd.ok())
return 0;
auto local_tp = ch::local_days { ymd } + ch::hours { hour } + ch::minutes { minute } + ch::seconds { second };
// 将本地时间根据当前系统时区转换为系统标准时间(UTC)
return ch::system_clock::to_time_t(ch::current_zone()->to_sys(local_tp));
}
catch (...)
{
std::tm stm {};
stm.tm_year = year - 1900;
stm.tm_mon = month - 1;
stm.tm_mday = day;
stm.tm_hour = hour;
stm.tm_min = minute;
stm.tm_sec = second;
stm.tm_isdst = -1;
return ::mktime(&stm);
}
}
time_t DateTime::SpanedSeconds(Span sp)
{
namespace ch = std::chrono;
auto total = ch::days { sp.days } + ch::hours { sp.hours } + ch::minutes { sp.minutes } + ch::seconds { sp.seconds };
return ch::duration_cast<ch::seconds>(total).count();
}
DateTime::Span DateTime::ToSpan(time_t tim)
{
// 修复了原代码中天数数额赋给秒、余数计算混乱的 Bug
namespace ch = std::chrono;
ch::seconds total_secs { tim };
auto d = ch::duration_cast<ch::days>(total_secs);
total_secs -= d;
auto h = ch::duration_cast<ch::hours>(total_secs);
total_secs -= h;
auto m = ch::duration_cast<ch::minutes>(total_secs);
total_secs -= m;
Span sp;
sp.days = static_cast<int>(d.count());
sp.hours = static_cast<int>(h.count());
sp.minutes = static_cast<int>(m.count());
sp.seconds = static_cast<int>(total_secs.count());
return sp;
}
DateTime::DateTime()
{
storage = ::time(nullptr);
UpdateDT();
}
DateTime::DateTime(time_t t)
{
storage = t;
UpdateDT();
}
DateTime::DateTime(const tm& stm)
{
storage = ::mktime(const_cast<tm*>(&stm));
UpdateDT();
}
DateTime::DateTime(const Full& ftm)
{
storage = FormatConvert(ftm.year, ftm.month, ftm.day, ftm.hour, ftm.minute, ftm.second);
UpdateDT();
}
DateTime::DateTime(int year, int month, int day, int hour, int minute, int second)
{
storage = FormatConvert(year, month, day, hour, minute, second);
UpdateDT();
}
DateTime::DateTime(const DateTime& obj)
{
storage = obj.storage;
sep_time = obj.sep_time;
}
DateTime DateTime::Now()
{
return DateTime(::time(nullptr));
}
time_t DateTime::GetTimeStamp() const
{
return storage;
}
int DateTime::GetYear() const
{
return sep_time.year;
}
int DateTime::GetMonth() const
{
return sep_time.month;
}
int DateTime::GetDay() const
{
return sep_time.day;
}
int DateTime::GetHour() const
{
return sep_time.hour;
}
int DateTime::GetMinute() const
{
return sep_time.minute;
}
int DateTime::GetSecond() const
{
return sep_time.second;
}
DateTime::Full DateTime::GetFullDateTime() const
{
return sep_time;
}
std::string DateTime::Format(std::string fmt_str)
{
namespace ch = std::chrono;
try
{
// 1. 获取系统标准时间点
auto tp = ch::system_clock::from_time_t(storage);
// 2. 转换为本地时间点
auto local_tp = ch::current_zone()->to_local(tp);
// 3. 截断到秒级精度(防止打印出纳秒/微秒的小数点),并获取 C++20 支持格式化的强类型
auto local_secs = ch::floor<ch::seconds>(local_tp);
// 4. 组装 C++20 chrono 格式化字符串并执行
std::string chrono_fmt = "{:" + fmt_str + "}";
return std::vformat(chrono_fmt, std::make_format_args(local_secs));
}
catch (...)
{
// 如果 C++20 运行时时区数据库不可用,或者 fmt_str 包含不兼容的传统旧语法,平滑降级
size_t size = (fmt_str.size() * 2) + 10;
auto recv = std::make_unique<char[]>(size);
std::tm suctm = static_cast<std::tm>(*this);
size_t ret = ::strftime(recv.get(), size, fmt_str.c_str(), &suctm);
while (ret == 0)
{
size *= 2;
recv = std::make_unique<char[]>(size);
ret = ::strftime(recv.get(), size, fmt_str.c_str(), &suctm);
}
return std::string(recv.get());
}
}
bool DateTime::IsAM()
{
return (sep_time.hour < 12);
} // 修正逻辑:通常12点后为PM
bool DateTime::IsPM()
{
return (sep_time.hour >= 12);
}
bool DateTime::TimePassed()
{
return (storage < ::time(nullptr));
} // 修正逻辑:过去的时间应该小于现在
DateTime::operator tm()
{
std::tm stm {};
stm.tm_year = sep_time.year - 1900;
stm.tm_mon = sep_time.month - 1;
stm.tm_mday = sep_time.day;
stm.tm_hour = sep_time.hour;
stm.tm_min = sep_time.minute;
stm.tm_sec = sep_time.second;
stm.tm_isdst = -1;
return stm;
}
DateTime::operator Full()
{
return sep_time;
}
DateTime::operator time_t()
{
return storage;
}
DateTime::operator std::string()
{
return Format("%Y-%m-%dT%H:%M:%S+08:00");
}
// ================== 运算符重载实现 ==================
DateTime::Span DateTime::operator-(const tm& stm)
{
return ToSpan(storage - ::mktime(const_cast<tm*>(&stm)));
}
DateTime::Span DateTime::operator-(const Span& ts)
{
return ToSpan(storage - SpanedSeconds(ts));
}
DateTime::Span DateTime::operator-(const Full& sdt)
{
return ToSpan(storage - FormatConvert(sdt.year, sdt.month, sdt.day, sdt.hour, sdt.minute, sdt.second));
}
DateTime::Span DateTime::operator-(const time_t& t)
{
return ToSpan(storage - t);
}
DateTime::Span DateTime::operator-(const DateTime& dt)
{
return ToSpan(storage - dt.storage);
}
DateTime::Span DateTime::operator+(const tm& stm)
{
return ToSpan(storage + ::mktime(const_cast<tm*>(&stm)));
}
DateTime::Span DateTime::operator+(const Span& ts)
{
return ToSpan(storage + SpanedSeconds(ts));
}
DateTime::Span DateTime::operator+(const Full& sdt)
{
return ToSpan(storage + FormatConvert(sdt.year, sdt.month, sdt.day, sdt.hour, sdt.minute, sdt.second));
}
DateTime::Span DateTime::operator+(const time_t& t)
{
return ToSpan(storage + t);
}
DateTime::Span DateTime::operator+(const DateTime& dt)
{
return ToSpan(storage + dt.storage);
}
DateTime DateTime::operator=(const tm& stm)
{
storage = ::mktime(const_cast<tm*>(&stm)); UpdateDT(); return *this;
}
DateTime DateTime::operator=(const Full& sdt)
{
storage = FormatConvert(sdt.year, sdt.month, sdt.day, sdt.hour, sdt.minute, sdt.second); UpdateDT(); return *this;
}
DateTime DateTime::operator=(const time_t& t)
{
storage = t; UpdateDT(); return *this;
}
DateTime DateTime::operator=(const DateTime& dt)
{
storage = dt.storage; UpdateDT(); return *this;
}
DateTime DateTime::operator+=(const tm& stm)
{
storage += ::mktime(const_cast<tm*>(&stm)); UpdateDT(); return *this;
}
DateTime DateTime::operator+=(const Span& ts)
{
storage += SpanedSeconds(ts); UpdateDT(); return *this;
}
DateTime DateTime::operator+=(const Full& sdt)
{
storage += FormatConvert(sdt.year, sdt.month, sdt.day, sdt.hour, sdt.minute, sdt.second); UpdateDT(); return *this;
}
DateTime DateTime::operator+=(const time_t& t)
{
storage += t; UpdateDT(); return *this;
}
DateTime DateTime::operator+=(const DateTime& dt)
{
storage += dt.storage; UpdateDT(); return *this;
}
DateTime DateTime::operator-=(const tm& stm)
{
storage -= ::mktime(const_cast<tm*>(&stm)); UpdateDT(); return *this;
}
DateTime DateTime::operator-=(const Span& ts)
{
storage -= SpanedSeconds(ts); UpdateDT(); return *this;
}
DateTime DateTime::operator-=(const Full& sdt)
{
storage -= FormatConvert(sdt.year, sdt.month, sdt.day, sdt.hour, sdt.minute, sdt.second); UpdateDT(); return *this;
}
DateTime DateTime::operator-=(const time_t& t)
{
storage -= t; UpdateDT(); return *this;
}
DateTime DateTime::operator-=(const DateTime& dt)
{
storage -= dt.storage; UpdateDT(); return *this;
}
bool DateTime::operator==(const tm& stm)
{
return storage == ::mktime(const_cast<tm*>(&stm));
}
bool DateTime::operator==(const Full& sdt)
{
return storage == FormatConvert(sdt.year, sdt.month, sdt.day, sdt.hour, sdt.minute, sdt.second);
}
bool DateTime::operator==(const time_t& t)
{
return storage == t;
}
bool DateTime::operator==(const DateTime& dt)
{
return storage == dt.storage;
}
bool DateTime::operator!=(const tm& stm)
{
return !(*this == stm);
}
bool DateTime::operator!=(const Full& sdt)
{
return !(*this == sdt);
}
bool DateTime::operator!=(const time_t& t)
{
return storage != t;
}
bool DateTime::operator!=(const DateTime& dt)
{
return storage != dt.storage;
}
bool DateTime::operator>(const tm& stm)
{
return storage > ::mktime(const_cast<tm*>(&stm));
}
bool DateTime::operator>(const Full& sdt)
{
return storage > FormatConvert(sdt.year, sdt.month, sdt.day, sdt.hour, sdt.minute, sdt.second);
}
bool DateTime::operator>(const time_t& t)
{
return storage > t;
}
bool DateTime::operator>(const DateTime& dt)
{
return storage > dt.storage;
}
bool DateTime::operator>=(const tm& stm)
{
return storage >= ::mktime(const_cast<tm*>(&stm));
}
bool DateTime::operator>=(const Full& sdt)
{
return storage >= FormatConvert(sdt.year, sdt.month, sdt.day, sdt.hour, sdt.minute, sdt.second);
}
bool DateTime::operator>=(const time_t& t)
{
return storage >= t;
}
bool DateTime::operator>=(const DateTime& dt)
{
return storage >= dt.storage;
}
bool DateTime::operator<(const tm& stm)
{
return storage < ::mktime(const_cast<tm*>(&stm));
}
bool DateTime::operator<(const Full& sdt)
{
return storage < FormatConvert(sdt.year, sdt.month, sdt.day, sdt.hour, sdt.minute, sdt.second);
}
bool DateTime::operator<(const time_t& t)
{
return storage < t;
}
bool DateTime::operator<(const DateTime& dt)
{
return storage < dt.storage;
}
bool DateTime::operator<(const DateTime& dt) const
{
return storage < dt.storage;
}
bool DateTime::operator<=(const tm& stm)
{
return storage <= ::mktime(const_cast<tm*>(&stm));
}
bool DateTime::operator<=(const Full& sdt)
{
return storage <= FormatConvert(sdt.year, sdt.month, sdt.day, sdt.hour, sdt.minute, sdt.second);
}
bool DateTime::operator<=(const time_t& t)
{
return storage <= t;
}
bool DateTime::operator<=(const DateTime& dt)
{
return storage <= dt.storage;
}