std :: chrono :: system_clock :: now()考虑操作系统configuration的时区

我正在编写一个在BusyBoxembedded式linux上运行的C ++代码。 我的代码和它的库有几个调用std::chrono::system_clock::now()来获取当前时间。

由于现在我的盒子被configuration为默认时区(UTC),一切正常,进程运行和结果ok。

现在我必须设置我的Linux留在不同的时区。 然后,我通过在/etc/profile

 export TZ=UTC+3 

当我发出date命令和控制台我得到正确的时间,但我对std::chrono::system_clock::now()调用我仍然得到UTC时间,而不是date命令中显示的date (正确的时间)。

我不想改变所有我now()电话 – 有数百个电话…这导致我的stream程在不同的时间工作,而不是正确的时间,在控制台上设置。

有没有办法解决这个问题,而不改变我的代码? 我在这里错过了什么?

感谢您的帮助。

尽管标准没有说明,但std::chrono::system_clock::now()每个实现都跟踪Unix时间 ,这与UTC非常接近。

如果你想将std::chrono::system_clock::now()翻译system_clock::time_point地时间,你可以通过system_clock::time_pointsystem_clock::time_pointtime_t ,然后通过C API(例如localtime ) ,或者你可以尝试这个建立在<chrono>之上的现代时区库:

https://howardhinnant.github.io/date/tz.html

你可以用这个获得当前的当地时间

 #include "tz.h" #include <iostream> int main() { using namespace date; using namespace std::chrono; auto t = make_zoned(current_zone(), system_clock::now()); std::cout << t << '\n'; } 

make_zoned是一个工厂函数,它以你的system_clock支持的任何精度(例如纳秒)返回zoned_time类型。 它是time_zonesystem_clock::time_point

你可以得到一个local_time<Duration>这是一个std::chrono::time_point像这样:

  auto t = make_zoned(current_zone(), system_clock::now()); auto lt = t.get_local_time(); std::cout << lt.time_since_epoch().count() << '\n'; 

尽管库有一个远程API来自动下载IANA时区数据库 ,但可以通过使用-DHAS_REMOTE_API=0进行编译来禁用该API。 这在安装说明中详细介绍。 在远程API被禁用的情况下,您将不得不从IANA时区数据库 (它只是一个tar.gz )手动下载数据库。

如果您需要当前的UTC偏移量,可以这样获得:

  auto t = make_zoned(current_zone(), system_clock::now()); auto offset = t.get_info().offset; std::cout << offset << '\n'; 

在上面的代码片段中,我利用在同一个github存储库中找到的"chrono_io.h"来打印offsetoffset类型为std::chrono::seconds 。 这只是为我输出:

 -14400s 

(-0400)

最后,如果您想要发现当前时区的IANA名称,那简直就是:

 std::cout << current_zone()->name() << '\n'; 

这对我来说只是输出:

 America/New_York 

name()返回的类型是std::string 。 如果需要,可以记录该字符串,然后使用具有该名称的time_zone ,即使这不是计算机的当前时区:

 auto tz_name = current_zone()->name(); // ... auto t = make_zoned(tz_name, system_clock::now()); // current local time in tz_name