IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> C++ 20 std::chrono 库使用 | std::chrono::year_month_day |std::chrono::hh_mm_ss 使用 -> 正文阅读

[C++知识库]C++ 20 std::chrono 库使用 | std::chrono::year_month_day |std::chrono::hh_mm_ss 使用

最近在写异步日志库,结果为了偷懒完全用 C++20 的功能发现 C++20 的 g++11 的 timezone 支持还没有做完,根据 cppreference 的统计 g++ 只是 partial 完成。我一用就直接报错了。。。

在 C++ 有一个日期时间库是 Howard Hinnant 的 date 库,但是太复杂了。最后我决定直接用 UTC+0 也就是格林威治时间了属于是(等 C++20 timezone 被 g++ 实现了再做时间转换吧)。

这里 mark 一下 C++20 怎么获取日期和时间(cppreference 对hh_mm_ss的没有样例属于,我一开始没搞清楚durationtime_point的区别搞不出来,搜索也没搜到什么帮助,看来搜索能力还要提高):

void test_chrono() {
  auto now = std::chrono::system_clock::now();
  // this is a duration
  std::chrono::duration<int64_t, std::nano> ss = now.time_since_epoch();
  // so is this one
  auto hh = std::chrono::floor<std::chrono::days>(ss);
  // this is a time point
  std::chrono::time_point<std::chrono::system_clock, std::chrono::days> tp = std::chrono::floor<std::chrono::days>(now);
  // hhmmss use a duration
  std::chrono::hh_mm_ss<std::chrono::milliseconds> tod{std::chrono::duration_cast<std::chrono::milliseconds>(ss - hh)};
  // ymd use a time point
  const std::chrono::year_month_day ymd(tp);
  std::cout << static_cast<int>(ymd.year()) << static_cast<unsigned>(ymd.month()) << static_cast<unsigned>(ymd.day()) << tod.hours().count() << tod.minutes().count() << tod.seconds().count()
            << tod.subseconds().count();
}

然后就可以大概地包装套娃一下写一个一个时间戳类了,不过只是简略包装一下了属于,没有大量测试之前知道这样用起来靠不靠谱,根据 C++ 20 的说明理论上是有类似 fmtlib 的 format_to 的实现的,不过目前好像只有 MSVC++ 支持,为了方便暂时还是先用 cstdio 做格式化了,而且这里因为做日志用的时间戳要缓存格式化好的日期避免重复格式化(格式化大概是 O(len) ? 如果只是比较一下就只是 O(1) 一秒内多次格式化差距还是挺大的),所以我直接做成写到 c style char array 里面的接口了,最简化了,由于日志功能主要给单个项目用的画,格式一般直接写死了避免太多转换的复杂度(虽然的确可以做成静态编译期处理),不做太多 accidental 的工作了:

class timestamp {
 private:
  static constexpr char TS_FMT_DATE[] = "%4d-%2u-%2u ";
  static constexpr char TS_FMT_BASE_TIME[] = "%02ld:%02ld:%02ld ";
  static constexpr char TS_FMT_MICRO_SEC[] = ".%06ld";

 public:
  static constexpr int fmt_date_len = sizeof TS_FMT_DATE;
  static constexpr int fmt_base_time_len = sizeof TS_FMT_BASE_TIME;
  static constexpr int fmt_micro_second_len = sizeof TS_FMT_MICRO_SEC;
  timestamp()
      : sys_timestamp_{std::chrono::system_clock::now()},
        ymd_data_{std::chrono::floor<std::chrono::days>(sys_timestamp_)},
        hms_data_{std::chrono::duration_cast<std::chrono::microseconds>(sys_timestamp_.time_since_epoch() - std::chrono::duration_cast<std::chrono::days>(sys_timestamp_.time_since_epoch()))} {}

  int year() { return static_cast<int>(ymd_data_.year()); }
  unsigned month() { return static_cast<unsigned>(ymd_data_.month()); }
  unsigned day() { return static_cast<unsigned>(ymd_data_.day()); }
  long hour() { return hms_data_.hours().count(); }
  long minute() { return hms_data_.minutes().count(); }
  long second() { return hms_data_.seconds().count(); }
  long microsecond() { return hms_data_.subseconds().count(); }

  bool compare_date(timestamp &rhs) {
    // TODO: is there a performance problem?
    return std::chrono::floor<std::chrono::days>(sys_timestamp_) == std::chrono::floor<std::chrono::days>(rhs.sys_timestamp_);
  }
  bool compare_second(timestamp &rhs) {
    // TODO:  is there a performance problem?
    return std::chrono::floor<std::chrono::seconds>(sys_timestamp_) == std::chrono::floor<std::chrono::seconds>(rhs.sys_timestamp_);
  }
  // use ptr if as output, use ref if as const reference (lvalue)
  // buf must larger than 4+2+2 + blanks
  char *format_date_to(char *buf) {
    int w = ::snprintf(buf, 50, TS_FMT_DATE, year(), month(), day());
    return buf + w;
  }
  char *format_base_time_to(char *buf) {
    int w = ::snprintf(buf, 50, TS_FMT_BASE_TIME, hour(), minute(), second());
    return buf + w;
  }
  char *format_micro_to(char *buf) {
    int w = ::snprintf(buf, 50, TS_FMT_MICRO_SEC, microsecond());
    return buf + w;
  }
  char *format_time_to(char *buf) {
    auto n = format_base_time_to(buf);
    auto w = format_micro_to(n);
    return w;
  }
  char *format_to(char *buf) {
    auto n = format_date_to(buf);
    auto w = format_time_to(n);
    return w;
  }

  std::string to_formatted_string() {
    char buf[40];
    auto n = format_to(buf);
    return buf;
  }

 private:
  const std::chrono::time_point<std::chrono::system_clock> sys_timestamp_;
  const std::chrono::year_month_day ymd_data_;
  const std::chrono::hh_mm_ss<std::chrono::microseconds> hms_data_;
};

打印结果是这样的,应该没写错了:
在这里插入图片描述
对于floortime_since_epoch以及 duration cast 的性能, 看了一下实现,要么是直接返回数据要么就是进行O(1)的 算数运算,应该不成问题。之后写完了会测一下。

参考:
https://en.cppreference.com/w/cpp/chrono/hh_mm_s
std::chrono::system_clock - cppreference.com
https://stackoverflow.com/questions/12927169/how-can-i-initialize-c-object-member-variables-in-the-constructor/12927220
http://www.cpp.re/forum/general/266667/ | Equivalent of <time.h> in - C++ Forum
https://github.com/HowardHinnant/date
https://gcc.gnu.org/projects/cxx-status.html | C++ Standards Support in GCC - GNU Project
https://docs.microsoft.com/en-us/cpp/standard-library/zoned-time-class?view=msvc-170 |

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2021-11-30 15:24:34  更:2021-11-30 15:27:51 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 9:51:25-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码