如何修复自定义OffsetZone以支持C++ zoned_time的流式输出?
修复自定义OffsetZone类以支持zoned_time流式输出
有一个自定义的OffsetZone时区类,可用于构造zoned_time对象,但尝试将zoned_time输出到cout时会报错,提示'get_info': is not a member of 'OffsetZone'。
原始OffsetZone代码
#include <chrono> class OffsetZone { std::chrono::minutes offset_; public: explicit OffsetZone(std::chrono::minutes offset) : offset_{offset} {} template <class Duration> auto to_local(std::chrono::sys_time<Duration> tp) const { return std::chrono::local_time{(tp + offset_).time_since_epoch()}; } template <class Duration> auto to_sys(std::chrono::local_time<Duration> tp) const { return std::chrono::sys_time{(tp - offset_).time_since_epoch()}; } const OffsetZone* operator->() const {return this;} };
出错的测试代码
#include <iostream> int main() { using namespace std::chrono; auto offset = 3h + 45min; OffsetZone tz{offset}; auto tp_utc = sys_days{2025y/5/3} + 22h; zoned_time zt{OffsetZone{offset}, tp_utc}; std::cout << zt << '\n'; }
报错信息
'get_info': is not a member of 'OffsetZone'
修复方案
流式输出zoned_time时,标准库会调用时区类的get_info成员函数,获取时区的偏移量、缩写等信息。因此需要给OffsetZone添加该函数,并返回符合要求的信息结构体。
修改后的完整OffsetZone类如下:
#include <chrono> #include <cstdio> #include <string> class OffsetZone { std::chrono::minutes offset_; // 生成时区缩写,格式为±HH:MM std::string get_abbrev() const { auto total_min = offset_.count(); auto hours = std::abs(total_min) / 60; auto mins = std::abs(total_min) % 60; char buf[8]; std::snprintf(buf, sizeof(buf), "%s%02d:%02d", total_min < 0 ? "-" : "+", static_cast<int>(hours), static_cast<int>(mins)); return buf; } public: explicit OffsetZone(std::chrono::minutes offset) : offset_{offset} {} template <class Duration> auto to_local(std::chrono::sys_time<Duration> tp) const { return std::chrono::local_time{(tp + offset_).time_since_epoch()}; } template <class Duration> auto to_sys(std::chrono::local_time<Duration> tp) const { return std::chrono::sys_time{(tp - offset_).time_since_epoch()}; } // 新增get_info函数,适配流式输出需求 template <class Duration> auto get_info(std::chrono::sys_time<Duration>) const { struct info { std::chrono::minutes offset; std::chrono::minutes save; std::string abbrev; }; return info{offset_, std::chrono::minutes{0}, get_abbrev()}; } const OffsetZone* operator->() const { return this; } };
测试验证
修改后运行原测试代码,会输出类似如下内容:
2025-05-04 01:45:00 +03:45
内容的提问来源于stack exchange,提问作者Howard Hinnant
相关产品推荐
相关产品推荐

