如何将std::chrono时区代码迁移至Howard Hinnant日期库?解决编译错误
修复UTC/本地时间转换代码迁移到Howard Hinnant日期库的编译错误
现有一段在MSVC下运行正常的C++20代码,使用std::chrono实现UTC与本地时间转换,但因GCC版本不支持timezone组件,改用Howard Hinnant日期库后,MSVC出现类型转换和函数匹配错误,具体信息如下:
原代码
#include <chrono> using LocalTime = std::chrono::time_point<std::chrono::local_t, std::chrono::system_clock::duration>; //using LocalTime = std::chrono::local_time<std::chrono::system_clock::duration>; using UtcTime = std::chrono::time_point<std::chrono::system_clock>; LocalTime UtcToLocal(UtcTime t) { auto tz = std::chrono::current_zone(); LocalTime tLocal = tz->to_local(t); return tLocal; } UtcTime LocalToUtc(LocalTime t) { auto tz = chronoExt::current_zone(); UtcTime tUtc = tz->to_sys(t); return tUtc; }
修改后代码
#include "tz.h" #include "date.h" LocalTime UtcToLocal(UtcTime t) { auto tz = date::current_zone(); LocalTime tLocal = tz->to_local(t); return tLocal; } UtcTime LocalToUtc(LocalTime t) { auto tz = date::current_zone(); UtcTime tUtc = tz->to_sys(t); return tUtc; }
编译错误信息
error C2440: 'initializing': cannot convert from 'std::chrono::time_point<date::local_t,std::chrono::duration<std::chrono::system_clock::rep,std::chrono::system_clock::period>>' to 'std::chrono::time_point<std::chrono::local_t,std::chrono::system_clock::duration>' message : No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called error C2672: 'date::time_zone::to_sys': no matching overloaded function found message : could be 'std::chrono::time_point<std::chrono::system_clock,common_type<_Duration,std::chrono::seconds>::type> date::time_zone::to_sys(std::chrono::time_point<date::local_t,Duration>,date::choose) const' message : 'std::chrono::time_point<std::chrono::system_clock,common_type<_Duration,std::chrono::seconds>::type> date::time_zone::to_sys(std::chrono::time_point<date::local_t,Duration>,date::choose) const': expects 2 arguments - 1 provided message : or 'std::chrono::time_point<std::chrono::system_clock,common_type<_Duration,std::chrono::seconds>::type> date::time_zone::to_sys(std::chrono::time_point<date::local_t,Duration>) const' message : 'std::chrono::time_point<std::chrono::system_clock,common_type<_Duration,std::chrono::seconds>::type> date::time_zone::to_sys(std::chrono::time_point<date::local_t,Duration>) const': could not deduce template argument for 'std::chrono::time_point<date::local_t,Duration>' from 'LocalTime'
错误原因与修复方案
错误根源
std::chrono::local_t和date::local_t是不同命名空间下的独立类型,无法隐式转换。原代码的LocalTime基于std::chrono::local_t,而Howard Hinnant库的to_local/to_sys接口使用date::local_t,导致类型不匹配。
修复后的完整代码
#include "tz.h" #include "date.h" // 使用date库的local_t统一本地时间类型,与库接口匹配 using LocalTime = std::chrono::time_point<date::local_t, std::chrono::system_clock::duration>; // 等价写法:直接使用date库提供的local_time模板 // using LocalTime = date::local_time<std::chrono::system_clock::duration>; using UtcTime = std::chrono::time_point<std::chrono::system_clock>; LocalTime UtcToLocal(UtcTime t) { auto tz = date::current_zone(); // 类型完全匹配,无需额外转换 return tz->to_local(t); } UtcTime LocalToUtc(LocalTime t) { auto tz = date::current_zone(); // 传入的LocalTime现在符合to_sys的参数类型要求 return tz->to_sys(t); }
可选兼容方案(保留std::chrono::local_t)
如果必须保留原代码中std::chrono::local_t的定义(比如其他代码依赖),可以通过duration显式转换类型:
// UtcToLocal修改如下 LocalTime UtcToLocal(UtcTime t) { auto tz = date::current_zone(); auto local_time = tz->to_local(t); // 用获取到的duration构造std::chrono::local_t的time_point return LocalTime{local_time.time_since_epoch()}; } // LocalToUtc修改如下 UtcTime LocalToUtc(LocalTime t) { auto tz = date::current_zone(); // 先将std::chrono::local_t转换为date::local_t的time_point date::local_time<std::chrono::system_clock::duration> date_local{t.time_since_epoch()}; return tz->to_sys(date_local); }
内容的提问来源于stack exchange,提问作者Martin Perry
相关产品推荐
相关产品推荐

