我的 C++20 代码在 MSVC 下运行良好。但是,我的 GCC 版本不支持时区,所以我想使用 Howard Hinnant 库。
#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;
}
在 MSVC 中我遇到错误:
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'
我推荐这样的东西:
即
#define USE_DATE_LIB 1
(或0
)告诉编译器在哪个命名空间中查找 C++20 chrono 位。在 MSVC 上使用USE_DATE_LIB = 0
,在 gcc(14 之前)上使用USE_DATE_LIB = 1
.然后你可以说:
事情应该会顺利进行。
可以让 Howard Hinnant 的日期库在 msvc 和 gcc 上运行 C++ 20。有一些优点,例如,如果您想确保 Windows 和 Linux 上有相同的时区数据库(或者如果您的 Windows 机器不够新,无法支持时区数据库),并且显然如果您无法升级出于公司原因,更新到最新的 gcc。不过,如果可以的话,我建议升级到 gcc13 ——我已经这样做了,一切都可以在 Windows 和 Linux 上运行:)。
要使日期库正常工作,您需要非常小心从哪个库中选择内容(即哪些位来自
date
以及哪些位来自std::chrono
)。我建议将您需要的内容导入std::chrono
到命名空间中dates
,然后dates
在整个代码中使用该命名空间。具体来说,就您而言,local_t
需要来自date
notstd::chrono
。IE为了让你的程序在有/没有dates.h的情况下进行编译,我设置了一些条件编译
(另请注意,如果您使用 HH 库的非常有用的 ostream 插入功能,则该
return (os << sys_time<Duration>{ut.time_since_epoch()});
行在 Visual C++ 中可能会被报告为不明确,在这种情况下可以更改为return date::operator<<(os, sys_time<Duration>{ut.time_since_epoch()});
。)