diff --git a/.clwb/.blaze/modules/.workspace.iml b/.clwb/.blaze/modules/.workspace.iml
index 74dcfe7..0d91316 100644
--- a/.clwb/.blaze/modules/.workspace.iml
+++ b/.clwb/.blaze/modules/.workspace.iml
@@ -9,6 +9,11 @@
+
+
+
+
+
diff --git a/BUILD.bazel b/BUILD.bazel
index f7ef562..81a7ad4 100644
--- a/BUILD.bazel
+++ b/BUILD.bazel
@@ -10,31 +10,34 @@ cc_library(
srcs = [],
hdrs = [],
copts = ["-I./src"],
+ linkopts = [
+ "-pthread",
+ "-ldl",
+ ],
deps = [
- "//src/logger:logger",
- "//src/logger:Logging",
- "//src/Base64:base64",
- "//src/BmpTool:BmpTool",
- "//src/C_VECTOR:c_vector",
- "//src/CGI:CGI",
- "//src/ConfigTool:ConfigTool",
- "//src/fastjson:fastjson",
- "//src/JSON:CJsonObject",
- "//src/json11:json11",
- "//src/littlefs:littlefs",
- # "//src/kHttpd:kHttpd",
- "//src/nlohmann:nlohmann_json",
- "//src/Pipe:Pipe",
- "//src/easyloggingpp:easyloggingpp",
- "//src/SHA1:SHA1",
- # "//src/socket:socket",
- "//src/thread_pool:thread_pool",
- "//src/xml:tinyxml2",
- "//src/UTF8Url:UTF8Url",
- # "//src/http:http",
- "//src/net_tool:net_tool",
- "//src/yaml-cpp:yaml-cpp",
- ],
- linkopts = ["-pthread","-ldl"],
+ "//src/logger",
+ "//src/logger:Logging",
+ "//src/Base64:base64",
+ "//src/BmpTool",
+ "//src/C_VECTOR:c_vector",
+ "//src/CGI",
+ "//src/ConfigTool",
+ "//src/fastjson",
+ "//src/JSON:CJsonObject",
+ "//src/json11",
+ "//src/littlefs",
+ # "//src/kHttpd:kHttpd",
+ "//src/nlohmann:nlohmann_json",
+ "//src/Pipe",
+ "//src/easyloggingpp",
+ "//src/SHA1",
+ "//src/date",
+ # "//src/socket:socket",
+ "//src/thread_pool",
+ "//src/xml:tinyxml2",
+ "//src/UTF8Url",
+ # "//src/http:http",
+ "//src/net_tool",
+ "//src/yaml-cpp",
+ ],
)
-
diff --git a/Example/BUILD.bazel b/Example/BUILD.bazel
index c360171..3b3fe19 100644
--- a/Example/BUILD.bazel
+++ b/Example/BUILD.bazel
@@ -10,3 +10,13 @@ cc_binary(
"//:Tools",
],
)
+
+cc_binary(
+ name = "testDate",
+ srcs = ["testDate.cpp"],
+ copts = [
+ ],
+ deps = [
+ "//:Tools",
+ ],
+)
diff --git a/Example/testDate.cpp b/Example/testDate.cpp
new file mode 100644
index 0000000..1cd0cc8
--- /dev/null
+++ b/Example/testDate.cpp
@@ -0,0 +1,32 @@
+//
+// Created by caesar kekxv on 2024/6/14.
+//
+#include
+#include
+#include
+
+int main(int argc, const char *argv[]) {
+ const auto date1 = clangTools::date::parse(1718372061);
+ std::cout << __LINE__ << ":" << date1->format() << std::endl;
+ const auto date2 = clangTools::date::parseMicroseconds(1718372061000);
+ std::cout << __LINE__ << ":" << date2->format() << std::endl;
+ const auto date3 = clangTools::date::parse(2024, 06 - 1, 14);
+ std::cout << __LINE__ << ":" << date3->format() << std::endl;
+ const auto date4 = clangTools::date::parse(2024, 06 - 1, 32, 8, 59);
+ std::cout << " " << date4->format("yyyy-MM-dd HH:mm:ss");
+ std::cout << "\t" << "yyyy-MM-dd HH:mm:ss" << std::endl;
+ std::cout << " " << *date4;
+ std::cout << "\t" << "yyyy-MM-dd HH:mm:ss" << std::endl;
+ std::cout << " " << date4->format("yyyy+1-MM-1-dd HH:mm:ss");
+ std::cout << "\t" << "yyyy+1-MM-1-dd HH:mm:ss" << std::endl;
+ std::cout << " " << date4->format("yyyy--06-dd HH:mm:ss");
+ std::cout << "\t" << "yyyy--06-dd HH:mm:ss" << std::endl;
+ std::cout << " " << date4->clone("yyyy-1-MM+1-dd HH:mm:ss")->format("yyyy-MM-dd HH:mm:ss");
+ std::cout << "\t" << "yyyy-1-MM+1-dd HH:mm:ss" << "_" << "yyyy-MM-dd HH:mm:ss" << std::endl;
+ std::cout << " " << date4->format("yyyy--07--02 HH:mm:ss");
+ std::cout << "\t" << "yyyy--07--02 HH:mm:ss" << std::endl;
+ std::cout << "\t" << date1 << std::endl;
+ std::cout << "\t" << date2 << std::endl;
+ std::cout << "\t" << (date1 == date2) << std::endl;
+ return 0;
+}
diff --git a/src/date/BUILD.bazel b/src/date/BUILD.bazel
new file mode 100644
index 0000000..0ad97ed
--- /dev/null
+++ b/src/date/BUILD.bazel
@@ -0,0 +1,11 @@
+cc_library(
+ name = "date",
+ srcs = [
+ "date.cpp",
+ ],
+ hdrs = [
+ "date.hpp",
+ ],
+ includes = ["."],
+ visibility = ["//visibility:public"],
+)
diff --git a/src/date/date.cpp b/src/date/date.cpp
new file mode 100644
index 0000000..b36bf94
--- /dev/null
+++ b/src/date/date.cpp
@@ -0,0 +1,216 @@
+//
+// Created by caesar kekxv on 2024/6/14.
+//
+
+#include "date.hpp"
+
+#include
+#include
+#include
+#include
+using namespace clangTools;
+
+std::shared_ptr date::now() {
+ return std::make_shared();
+}
+
+std::shared_ptr date::parse(const int year, const int monthIndex, const int day, const int hours, const int minutes, const int seconds, const int milliseconds) {
+ struct tm time{};
+ time.tm_year = year - 1900;
+ time.tm_mon = monthIndex;
+ time.tm_mday = day;
+ time.tm_hour = hours;
+ time.tm_min = minutes;
+ time.tm_sec = seconds;
+ calc_tm(&time);
+ auto date_ = parse(std::mktime(&time));
+ date_->m_time_point = date_->m_time_point + std::chrono::milliseconds(milliseconds);
+ return date_;
+}
+
+date::~date() = default;
+
+/**
+ * 重置时间点
+ */
+void date::reset() {
+ m_time_point = system_clk::now();
+}
+
+/**
+ * 解析时间
+ * @param src 时间
+ * @param format_string 时间格式
+ * @return 是否解析成功
+ */
+std::shared_ptr date::parse(const std::string &src, const char *format_string) {
+ std::stringstream ss{src};
+ std::tm dt{};
+ ss >> std::get_time(&dt, replace_format(format_string).c_str());
+ const time_t c_time_t = std::mktime(&dt);
+ return parse(c_time_t);
+}
+
+/**
+ * 解析时间戳,只支持秒
+ * @param time_ 时间戳
+ * @return 是否解析成功
+ */
+std::shared_ptr date::parse(const std::time_t &time_) {
+ auto date_ = now();
+ date_->m_time_point = system_clk::from_time_t(time_);
+ return date_;
+}
+
+/**
+ * 解析时间戳,只支持毫秒
+ * @param time_ 时间戳
+ * @return 是否解析成功
+ */
+std::shared_ptr date::parseMicroseconds(const std::time_t &time_) {
+ return parse(time_ / 1000);
+}
+
+std::shared_ptr date::clone(const char *format_string) const {
+ const auto t = format(format_string);
+ auto format_string_ = std::regex_replace(format_string, std::regex{"--"}, "||");
+ format_string_ = std::regex_replace(format_string_, std::regex{"[+-]\\d+"}, "");
+ format_string_ = std::regex_replace(format_string_, std::regex{"||"}, "-");
+ return parse(t, format_string_.c_str());
+}
+
+/**
+ * 时间
+ * @param format_string 解析格式
+ * @return 格式化的时间
+ */
+std::string date::format(const char *format_string) const {
+ auto format_string_ = replace_format(format_string);
+ format_string_ = std::regex_replace(format_string_, std::regex{"--"}, "||");
+ const std::regex reg("([YyMdHlmS])([-+]\\d+)");
+ std::smatch m;
+ auto pos = format_string_.cbegin();
+ const std::time_t c_time_t = system_clk::to_time_t(m_time_point);
+ const auto t_ = std::localtime(&c_time_t);
+ struct tm t{};
+ memcpy(&t, t_, sizeof(struct tm));
+ for (const auto end = format_string_.cend(); std::regex_search(pos, end, m, reg); pos = m.suffix().first) {
+ const int offset = static_cast(strtol(m.str(2).c_str(), nullptr, 10));
+ switch (m.str(1)[0]) {
+ case 'Y':
+ case 'y':
+ t.tm_year += offset;
+ break;
+ case 'm':
+ t.tm_mon += offset;
+ break;
+ case 'd':
+ t.tm_mday += offset;
+ break;
+ case 'l':
+ case 'H':
+ t.tm_hour += offset;
+ break;
+ case 'M':
+ t.tm_min += offset;
+ break;
+ case 'S':
+ t.tm_sec += offset;
+ break;
+ default:
+ break;
+ }
+ }
+ calc_tm(&t);
+ format_string_ = std::regex_replace(format_string_, std::regex{"[+-]\\d+"}, "");
+ format_string_ = std::regex_replace(format_string_, std::regex{"||"}, "-");
+ char mbstr[100]{};
+ const size_t size = std::strftime(mbstr, sizeof(mbstr), format_string_.c_str(), &t);
+ std::string result{};
+ if (size) {
+ result.insert(result.end(), mbstr, mbstr + size);
+ }
+ return result;
+}
+
+std::string date::to_string(const char *format_string) const {
+ return format(format_string);
+}
+
+int date::calc_max_day(const int year, const int mon) {
+ int max_day = 31;
+ switch (mon + 1) {
+ case 2:
+ if (year % 100 == 0) {
+ max_day = year % 400 == 0 ? 29 : 28;
+ } else {
+ max_day = year % 4 == 0 ? 29 : 28;
+ }
+ break;
+ case 1:
+ case 3:
+ case 5:
+ case 7:
+ case 8:
+ case 10:
+ case 12:
+ max_day = 31;
+ break;
+ case 4:
+ case 6:
+ case 9:
+ case 11:
+ default:
+ max_day = 30;
+ break;
+ }
+ return max_day;
+}
+
+void date::calc_tm(struct tm *tm_) {
+ if (tm_->tm_sec < 0) { tm_->tm_sec = 0; } else if (tm_->tm_sec >= 60) {
+ tm_->tm_sec = tm_->tm_sec - 60;
+ tm_->tm_min = tm_->tm_min + 1;
+ }
+ if (tm_->tm_min < 0) { tm_->tm_min = 0; } else if (tm_->tm_min >= 60) {
+ tm_->tm_min = tm_->tm_min - 60;
+ tm_->tm_hour = tm_->tm_hour + 1;
+ }
+ if (tm_->tm_hour < 0) { tm_->tm_hour = 0; } else if (tm_->tm_hour >= 24) {
+ tm_->tm_hour = tm_->tm_hour - 24;
+ tm_->tm_mday = tm_->tm_mday + 1;
+ }
+ do {
+ const auto max_day = calc_max_day(tm_->tm_year + 1900, tm_->tm_mon);
+ if (tm_->tm_mday < 1) { tm_->tm_mday = 1; } else if (tm_->tm_mday > max_day) {
+ tm_->tm_mday = tm_->tm_mday - max_day;
+ tm_->tm_mon = tm_->tm_mon + 1;
+ }
+ if (tm_->tm_mon < 0) { tm_->tm_mon = 0; } else if (tm_->tm_mon >= 12) {
+ tm_->tm_mon = tm_->tm_mon - 12;
+ tm_->tm_year = tm_->tm_year + 1;
+ const auto max_day_now = calc_max_day(tm_->tm_year, tm_->tm_mon);
+ if (max_day_now != max_day)continue;
+ }
+ break;
+ } while (true);
+}
+
+std::string date::replace_format(const char *format_string) {
+ auto s = std::regex_replace(format_string, std::regex{"([dHSaAwWzZ])+"}, "%$1");
+ if (std::regex_search(s, std::regex{"y{3,}", std::regex::icase})) {
+ s = std::regex_replace(s, std::regex{"[Yy]+"}, "%Y");
+ } else {
+ s = std::regex_replace(s, std::regex{"[Yy]+"}, "%y");
+ }
+ // 过度变量字符
+ s = std::regex_replace(s, std::regex{"m+"}, "、、");
+ s = std::regex_replace(s, std::regex{"M+"}, "%m");
+ s = std::regex_replace(s, std::regex{"、、"}, "%M");
+ s = std::regex_replace(s, std::regex{"h+"}, "%l");
+ s = std::regex_replace(s, std::regex{"s+"}, "%S");
+ return s;
+}
+
+date::date(): m_time_point(system_clk::now()) {
+}
diff --git a/src/date/date.hpp b/src/date/date.hpp
new file mode 100644
index 0000000..9cd2bdd
--- /dev/null
+++ b/src/date/date.hpp
@@ -0,0 +1,154 @@
+//
+// Created by caesar kekxv on 2024/6/14.
+//
+
+#ifndef CLANGTOOLS_DATE_HPP
+#define CLANGTOOLS_DATE_HPP
+#include
+#include
+#include
+
+namespace clangTools {
+ class date {
+ // 重命名system_clock名称空间
+ using system_clk = std::chrono::system_clock;
+ // 重命名time_point类型
+ using _time_point = std::chrono::time_point;
+
+ public:
+ static std::shared_ptr now();
+
+ /**
+ * 创建时间对象
+ * @param year 年
+ * @param monthIndex 月:0-11
+ * @param day 天
+ * @param hours 小时
+ * @param minutes 分钟
+ * @param seconds 秒
+ * @param milliseconds 毫秒
+ * @return 时间
+ */
+ static std::shared_ptr parse(int year, int monthIndex, int day = 1, int hours = 0, int minutes = 0, int seconds = 0, int milliseconds = 0);
+
+ /**
+ * 解析时间
+ * @param src 时间
+ * @param format_string 时间格式
+ * @return 是否解析成功
+ */
+ static std::shared_ptr parse(const std::string &src, const char *format_string = "yyyy-MM-dd HH:mm:ss");
+
+ /**
+ * 解析时间戳,只支持秒
+ * @param time_ 时间戳
+ * @return 是否解析成功
+ */
+ static std::shared_ptr parse(const std::time_t &time_);
+
+ /**
+ * 解析时间戳,只支持毫秒
+ * @param time_ 时间戳
+ * @return 是否解析成功
+ */
+ static std::shared_ptr parseMicroseconds(const std::time_t &time_);
+
+ ~date();
+
+ explicit date();
+
+ /**
+ * 重置时间点
+ */
+ void reset();
+
+
+ /**
+ * 时间
+ * @param format_string 解析格式
+ * @return 格式化的时间
+ */
+ std::string format(const char *format_string = "yyyy-MM-dd HH:mm:ss") const;
+
+ /**
+ * 转字符串
+ * @param format_string 格式
+ * @return 字符串
+ */
+ std::string to_string(const char *format_string = "yyyy-MM-dd HH:mm:ss") const;
+
+ /**
+ * 克隆一个对象
+ * @param format_string 格式,支持 "yyyy+1-MM-1-dd HH:mm:ss" 如果是 "yyyy-01-01 HH:mm:ss",需要改为 "yyyy--01--01 HH:mm:ss",否则解析错误
+ * @return 新的对象
+ */
+ std::shared_ptr clone(const char *format_string = "yyyy-MM-dd HH:mm:ss") const;
+
+ public:
+ date &operator=(const date &date_) = default;
+
+ date &operator=(const std::shared_ptr &date_) {
+ m_time_point = date_->m_time_point;
+ return (*this);
+ }
+
+ friend std::ostream &operator<<(std::ostream &output, const date &date_) {
+ output << date_.to_string();
+ return output;
+ }
+
+ friend std::ostream &operator<<(std::ostream &output, const std::shared_ptr &date_) {
+ output << date_->to_string();
+ return output;
+ }
+
+ friend std::istream &operator>>(std::istream &input, date &date_) {
+ std::string str;
+ input >> str;
+ date_ = date::parse(str);
+ return input;
+ }
+
+ friend bool operator>(const date &d1, const date &d2) { return d1.m_time_point > d2.m_time_point; }
+ friend bool operator>(const std::shared_ptr &d1, const std::shared_ptr &d2) { return *d1 > *d2; }
+ friend bool operator>(const date &d1, const std::shared_ptr &d2) { return d1 > *d2; }
+ friend bool operator>(const std::shared_ptr &d1, const date &d2) { return *d1 > d2; }
+
+ friend bool operator>=(const date &d1, const date &d2) { return d1.m_time_point >= d2.m_time_point; }
+ friend bool operator>=(const std::shared_ptr &d1, const std::shared_ptr &d2) { return *d1 >= *d2; }
+ friend bool operator>=(const date &d1, const std::shared_ptr &d2) { return d1 >= *d2; }
+ friend bool operator>=(const std::shared_ptr &d1, const date &d2) { return *d1 >= d2; }
+
+ friend bool operator<(const date &d1, const date &d2) { return d1.m_time_point < d2.m_time_point; }
+ friend bool operator<(const std::shared_ptr &d1, const std::shared_ptr &d2) { return *d1 < *d2; }
+ friend bool operator<(const date &d1, const std::shared_ptr &d2) { return d1 < *d2; }
+ friend bool operator<(const std::shared_ptr &d1, const date &d2) { return *d1 < d2; }
+
+ friend bool operator<=(const date &d1, const date &d2) { return d1.m_time_point <= d2.m_time_point; }
+ friend bool operator<=(const std::shared_ptr &d1, const std::shared_ptr &d2) { return *d1 <= *d2; }
+ friend bool operator<=(const date &d1, const std::shared_ptr &d2) { return d1 <= *d2; }
+ friend bool operator<=(const std::shared_ptr &d1, const date &d2) { return *d1 <= d2; }
+
+ friend bool operator==(const date &d1, const date &d2) { return d1.m_time_point == d2.m_time_point; }
+ friend bool operator==(const std::shared_ptr &d1, const std::shared_ptr &d2) { return *d1 == *d2; }
+ friend bool operator==(const date &d1, const std::shared_ptr &d2) { return d1 == *d2; }
+ friend bool operator==(const std::shared_ptr &d1, const date &d2) { return *d1 == d2; }
+
+ friend bool operator!=(const date &d1, const date &d2) { return d1.m_time_point != d2.m_time_point; }
+ friend bool operator!=(const std::shared_ptr &d1, const std::shared_ptr &d2) { return *d1 != *d2; }
+ friend bool operator!=(const date &d1, const std::shared_ptr &d2) { return d1 != *d2; }
+ friend bool operator!=(const std::shared_ptr &d1, const date &d2) { return *d1 != d2; }
+
+ private:
+ static int calc_max_day(int year, int mon);
+
+ static void calc_tm(struct tm *tm_);
+
+ static std::string replace_format(const char *format_string = "yyyy-MM-dd HH:mm:ss");
+
+ private:
+ _time_point m_time_point;
+ };
+}
+
+#endif //CLANGTOOLS_DATE_HPP