最近在写异步日志库,结果为了偷懒完全用 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 durationstd::chrono::duration<int64_t, std::nano> ss = now.time_since_epoch();// so is this oneauto hh = std::chrono::floor<std::chrono::days>(ss);// this is a time pointstd::chrono::time_point<std::chrono::system_clock, std::chrono::days> tp = std::chrono::floor<std::chrono::days>(now);// hhmmss use a durationstd::chrono::hh_mm_ss<std::chrono::milliseconds> tod{std::chrono::duration_cast<std::chrono::milliseconds>(ss - hh)};// ymd use a time pointconst 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 + blankschar *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++ 20 std::chrono 库使用 | std::chrono::year_month_day |std::chrono::hh_mm_ss 使用相关推荐

  1. chrono是一个time library,C++11 std::chrono库详解

    C++11 std::chrono库详解 chrono是一个time library, 源于boost,现在已经是C++标准.话说今年似乎又要出新标准了,好期待啊! 要使用chrono库,需要#inc ...

  2. 时间编程Chrono库 - C++11

    chrono库主要包含了三种类型:时间间隔Duration.时钟Clocks和时间点Time point.时钟是系统内部不断循环执行的时钟,某个一点对应的是时间点timepoint,两个时间点之间的差 ...

  3. C++ Clock和Timer(chrono库)

    原文链接: Clock和Timer(chrono库) 一.Clock和Timer 在过去,C和POSIX提供的系统时间接口,允许从秒转换至毫秒,再至微秒,最终至纳秒,问题是每次转换就需要一个新接口 基 ...

  4. C++(标准库):10---Clock和Timer(chrono库)

    一.Clock和Timer 在过去,C和POSIX提供的系统时间接口,允许从秒转换至毫秒,再至微秒,最终至纳秒,问题是每次转换就需要一个新接口 基于这个原因,C++11开始提供一个精度中立的程序库,称 ...

  5. C++11 处理时间和日期的处理,以及chrono库介绍

    C++11提供了日期和时间相关的库chrono,通过这个库可以很方便的对时间和日期进行处理: chrono库主要包含三种类型: 1.时间间隔duration 介绍一下duraton的原型: templ ...

  6. C++11 中chrono库 实现高精度定时

    一种"传统"ctime计时方法: #include <ctime> using namespace std;clock_t start = clock(); // do ...

  7. C++11的chrono库,可实现毫秒微秒级定时

    C++11有了chrono库,可以很容易的实现定时功能. chrono: chrono库主要包含了三种类型:时间间隔Duration.时钟Clocks和时间点Time point. Duration: ...

  8. (笔记)处理日期和时间的方法(chrono 库,time_t等)

    文章目录 0 摘要 1 chrono 库 1.1 时间间隔duration 1.2 时间点time point 1.3 时钟clocks 1.3.1 system_clock 1.3.2 steady ...

  9. C++处理日期和时间的chrono库

    C++11 中提供了日期和时间相关的库 chrono,通过 chrono 库可以很方便地处理日期和时间,为程序的开发提供了便利.chrono 库主要包含三种类型的类:时间间隔duration.时钟cl ...

最新文章

  1. 英伟达一大波硬件来袭:今日GTC发布专业GPU与DPU,为收购ARM将在英国建超算
  2. 前端开发中的 正则表达式 及常用正则表达式大全
  3. 使用visualvm远程监控LINUX服务器JVM
  4. Cube 技术解读 | 支付宝新一代动态化技术架构与选型综述
  5. 用Unity3D实现简单的牧师与魔鬼游戏
  6. thinkpad如何屏蔽bios更新 提示电池_有种血赚叫“二手”!3000搞定原价万元ThinkPad小黑本,真省钱...
  7. php workman 多线程,workerman如何多线程
  8. Flume与Kafka整合案例详解
  9. 20172316 结对编程-四则运算 第一周 阶段总结
  10. 虚拟机配置centos7.5网卡网络
  11. mac查看电脑系统位数
  12. matlab中mov是什么意思,PLC编程中MOV是什么意思
  13. DICOMRT:XXX Target Volume,各种目标体积浅析
  14. 金融数据api接口记录(二)
  15. 蛋白摄入量与常见饮食
  16. 微信SDK非ipad协议
  17. openssl工具详解及自建CA方法
  18. python数据分析实战之异常值处理
  19. 洛谷刷题C语言:闰年判断、Apples、洛谷团队系统、肥胖问题、三位数排序
  20. 网页设计HTML个人笔记

热门文章

  1. 我们需要多大的电视?
  2. js下载文件方法记录
  3. 解决Maven通过ojdbc连接Oracle
  4. python爬虫 — 爬取淘宝商品信息
  5. 合适的教育ERP管理系统,可让你省去很多麻烦
  6. 使用freemarker导出html格式的word(调整页边距,页面视图,正常表格样式)
  7. PLX PCIe Switch使用
  8. input变灰禁止输入状态
  9. cocos2d-js 苹果 刘海屏 适配
  10. UCS-2 编码范围