#ifndef A283B06E_3ED5_4D78_A2B5_4B87495A80A6 #define A283B06E_3ED5_4D78_A2B5_4B87495A80A6 #include #include #include #include #include "Poco/DateTime.h" #include "Poco/DateTimeFormat.h" #include "Poco/DateTimeFormatter.h" #include "Poco/DateTimeParser.h" #include "Poco/Exception.h" #include "Poco/LocalDateTime.h" #include "Poco/Timespan.h" #include "Poco/Timestamp.h" namespace Util { class DateTimeUtils { public: static Poco::DateTime now() { return Poco::DateTime(); } static Poco::LocalDateTime localNow() { return Poco::LocalDateTime(); } static std::string nowStr(const std::string& formatStr = "%Y-%m-%d %H:%M:%S") { return format(Poco::DateTime(), formatStr); } static std::string localNowStr(const std::string& formatStr = "%Y-%m-%d %H:%M:%S") { return Poco::DateTimeFormatter::format(Poco::LocalDateTime(), formatStr); } static Poco::DateTime parse(const std::string& str, const std::string& formatStr = "") { auto dt = Poco::DateTime(1970, 1, 1); if (str.empty()) { return dt; } int timeZoneDifferential = 0; if (!formatStr.empty()) { if (Poco::DateTimeParser::tryParse(formatStr, str, dt, timeZoneDifferential)) { return dt; } } else { if (Poco::DateTimeParser::tryParse(Poco::DateTimeFormat::ISO8601_FORMAT, str, dt, timeZoneDifferential) || Poco::DateTimeParser::tryParse("%Y-%m-%d %H:%M:%S", str, dt, timeZoneDifferential) || Poco::DateTimeParser::tryParse("%Y/%m/%d %H:%M:%S", str, dt, timeZoneDifferential) || Poco::DateTimeParser::tryParse("%Y%m%d%H%M%S", str, dt, timeZoneDifferential)) { return dt; } } return dt; } static std::string format(const Poco::DateTime& dt, const std::string& formatStr = "%Y-%m-%d %H:%M:%S") { return Poco::DateTimeFormatter::format(dt, formatStr); } static std::string toISO8601(const Poco::DateTime& dt) { return Poco::DateTimeFormatter::format(dt, Poco::DateTimeFormat::ISO8601_FORMAT); } static std::string toRFC1123(const Poco::DateTime& dt) { return Poco::DateTimeFormatter::format(dt, Poco::DateTimeFormat::RFC1123_FORMAT); } static Poco::DateTime addDays(const Poco::DateTime& dt, int days) { return dt + Poco::Timespan(days, 0, 0, 0, 0); } static Poco::DateTime addHours(const Poco::DateTime& dt, int hours) { return dt + Poco::Timespan(0, hours, 0, 0, 0); } static Poco::DateTime addMinutes(const Poco::DateTime& dt, int minutes) { return dt + Poco::Timespan(0, 0, minutes, 0, 0); } static Poco::DateTime addSeconds(const Poco::DateTime& dt, int seconds) { return dt + Poco::Timespan(0, 0, 0, seconds, 0); } static Poco::Timespan diff(const Poco::DateTime& dt1, const Poco::DateTime& dt2) { Poco::Timestamp ts1 = dt1.timestamp(); Poco::Timestamp ts2 = dt2.timestamp(); Poco::Timestamp::TimeDiff diffMicroseconds = 0; if (ts1 > ts2) { diffMicroseconds = ts1 - ts2; } else { diffMicroseconds = ts2 - ts1; } return Poco::Timespan(diffMicroseconds); } static long diffSeconds(const Poco::DateTime& dt1, const Poco::DateTime& dt2) { Poco::Timestamp ts1 = dt1.timestamp(); Poco::Timestamp ts2 = dt2.timestamp(); Poco::Timestamp::TimeDiff diffMicroseconds = 0; if (ts1 > ts2) { diffMicroseconds = ts1 - ts2; } else { diffMicroseconds = ts2 - ts1; } Poco::Timespan ts(diffMicroseconds); return ts.totalSeconds(); } static long long diffMilliseconds(const Poco::DateTime& dt1, const Poco::DateTime& dt2) { Poco::Timestamp ts1 = dt1.timestamp(); Poco::Timestamp ts2 = dt2.timestamp(); Poco::Timestamp::TimeDiff diffMicroseconds = 0; if (ts1 > ts2) { diffMicroseconds = ts1 - ts2; } else { diffMicroseconds = ts2 - ts1; } return diffMicroseconds / 1000; } static long long diffMicroseconds(const Poco::DateTime& dt1, const Poco::DateTime& dt2) { Poco::Timestamp ts1 = dt1.timestamp(); Poco::Timestamp ts2 = dt2.timestamp(); Poco::Timestamp::TimeDiff diffMicroseconds = 0; if (ts1 > ts2) { diffMicroseconds = ts1 - ts2; } else { diffMicroseconds = ts2 - ts1; } return diffMicroseconds; } static void diffComponents(const Poco::DateTime& dt1, const Poco::DateTime& dt2, int& days, int& hours, int& minutes, int& seconds) { Poco::Timespan ts = diff(dt1, dt2); days = ts.days(); hours = ts.hours(); minutes = ts.minutes(); seconds = ts.seconds(); } static Poco::Timespan calculateDifference(const Poco::DateTime& dt1, const Poco::DateTime& dt2) { Poco::Timestamp::TimeVal us1 = dt1.timestamp().epochMicroseconds(); Poco::Timestamp::TimeVal us2 = dt2.timestamp().epochMicroseconds(); Poco::Timestamp::TimeVal diff = 0; if (us1 > us2) { diff = us1 - us2; } else { diff = us2 - us1; } return Poco::Timespan(diff); } static bool isBefore(const Poco::DateTime& dt1, const Poco::DateTime& dt2) { Poco::Timestamp ts1 = dt1.timestamp(); Poco::Timestamp ts2 = dt2.timestamp(); return ts1 < ts2; } static bool isAfter(const Poco::DateTime& dt1, const Poco::DateTime& dt2) { Poco::Timestamp ts1 = dt1.timestamp(); Poco::Timestamp ts2 = dt2.timestamp(); return ts1 > ts2; } static bool isEqual(const Poco::DateTime& dt1, const Poco::DateTime& dt2) { Poco::Timestamp ts1 = dt1.timestamp(); Poco::Timestamp ts2 = dt2.timestamp(); return ts1 == ts2; } static bool isLeapYear(int year) { return Poco::DateTime::isLeapYear(year); } static int daysInMonth(int year, int month) { if (month < 1 || month > 12) { return 0; } Poco::DateTime nextMonth; if (month == 12) { nextMonth = Poco::DateTime(year + 1, 1, 1); } else { nextMonth = Poco::DateTime(year, month + 1, 1); } Poco::DateTime lastDay = nextMonth - Poco::Timespan(1, 0, 0, 0, 0); return lastDay.day(); } static std::string getWeekdayName(int dayOfWeek) { static const std::string weekdays[] = {"星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"}; if (dayOfWeek >= 0 && dayOfWeek <= 6) { return weekdays[dayOfWeek]; } return "未知"; } static time_t getTimestamp() { Poco::Timestamp ts; return ts.epochTime(); } static long long getTimestampMs() { Poco::Timestamp ts; return ts.epochMicroseconds() / 1000; } static long long getTimestampUs() { Poco::Timestamp ts; return ts.epochMicroseconds(); } static Poco::DateTime fromTimestamp(time_t timestamp) { Poco::Timestamp ts(static_cast(timestamp) * 1000000); return Poco::DateTime(ts); } static Poco::DateTime fromTimestampMs(long long timestampMs) { Poco::Timestamp ts(static_cast(timestampMs) * 1000); return Poco::DateTime(ts); } static Poco::DateTime fromTimestampUs(long long timestampUs) { Poco::Timestamp ts(static_cast(timestampUs)); return Poco::DateTime(ts); } static Poco::Timestamp toTimestamp(const Poco::DateTime& dt) { return dt.timestamp(); } static Poco::DateTime toDateTime(const Poco::Timestamp& ts) { return Poco::DateTime(ts); } static Poco::DateTime getStartOfDay(const Poco::DateTime& dt) { return Poco::DateTime(dt.year(), dt.month(), dt.day()); } static Poco::DateTime getEndOfDay(const Poco::DateTime& dt) { return Poco::DateTime(dt.year(), dt.month(), dt.day(), 23, 59, 59, 999999); } static int getAge(const Poco::DateTime& birthDate) { Poco::DateTime now = DateTimeUtils::now(); int age = now.year() - birthDate.year(); if (now.month() < birthDate.month() || (now.month() == birthDate.month() && now.day() < birthDate.day())) { age--; } return age; } static bool isSameDay(const Poco::DateTime& dt1, const Poco::DateTime& dt2) { return dt1.year() == dt2.year() && dt1.month() == dt2.month() && dt1.day() == dt2.day(); } static std::string formatTimespan(const Poco::Timespan& ts) { std::string result; if (ts.days() > 0) { result += std::to_string(ts.days()) + "天"; } if (ts.hours() > 0) { result += std::to_string(ts.hours()) + "小时"; } if (ts.minutes() > 0) { result += std::to_string(ts.minutes()) + "分"; } if (ts.seconds() > 0) { result += std::to_string(ts.seconds()) + "秒"; } if (result.empty()) { result = "0秒"; } return result; } static std::string formatTimeDifference(const Poco::DateTime& dt1, const Poco::DateTime& dt2) { Poco::Timespan diff = calculateDifference(dt1, dt2); return formatTimespan(diff); } static std::string formatTimespanWithMs(const Poco::Timespan& ts) { std::string result = formatTimespan(ts); int milliseconds = ts.milliseconds(); if (milliseconds > 0) { result += std::to_string(milliseconds) + "毫秒"; } return result; } static int getWeekOfYear(const Poco::DateTime& dt) { Poco::DateTime firstDay(dt.year(), 1, 1); Poco::Timespan diff = dt - firstDay; int dayOfYear = diff.days() + 1; int firstDayWeek = firstDay.dayOfWeek(); int week = (dayOfYear + firstDayWeek - 1) / 7 + 1; return week; } static Poco::DateTime getFirstDayOfMonth(const Poco::DateTime& dt) { return Poco::DateTime(dt.year(), dt.month(), 1); } static Poco::DateTime getLastDayOfMonth(const Poco::DateTime& dt) { int lastDay = daysInMonth(dt.year(), dt.month()); return Poco::DateTime(dt.year(), dt.month(), lastDay); } static Poco::DateTime getFirstDayOfWeek(const Poco::DateTime& dt) { int dayOfWeek = dt.dayOfWeek(); int daysToMonday = (dayOfWeek == 0) ? 6 : (dayOfWeek - 1); return addDays(dt, -daysToMonday); } static Poco::DateTime getLastDayOfWeek(const Poco::DateTime& dt) { int dayOfWeek = dt.dayOfWeek(); int daysToSunday = (dayOfWeek == 0) ? 0 : (7 - dayOfWeek); return addDays(dt, daysToSunday); } static long long getTime(const Poco::DateTime& dt) { Poco::Timestamp ts = dt.timestamp(); return ts.epochMicroseconds() / 1000; } static time_t getTimeSeconds(const Poco::DateTime& dt) { Poco::Timestamp ts = dt.timestamp(); return ts.epochTime(); } static Poco::DateTime fromTime(long long milliseconds) { Poco::Timestamp ts(static_cast(milliseconds) * 1000); return Poco::DateTime(ts); } static Poco::DateTime fromTimeSeconds(time_t seconds) { Poco::Timestamp ts(static_cast(seconds) * 1000000); return Poco::DateTime(ts); } static long long currentTimeMillis() { Poco::Timestamp ts; return ts.epochMicroseconds() / 1000; } static time_t currentTimeSeconds() { Poco::Timestamp ts; return ts.epochTime(); } }; } #endif