我正在编写一个在BusyBox嵌入式Linux上运行的C ++代码。我的代码及其库有几次调用std::chrono::system_clock::now()
来获取当前时间。
从现在开始我的盒子配置为dafault时区(UTC),一切正常,进程正常运行,结果还可以。
现在我必须设置我的linux以保持不同的时区。然后我通过在/etc/profile
框中配置来完成它:
export TZ=UTC+3
当我发出date
命令和控制台时,我得到了正确的时间,但我对std::chrono::system_clock::now()
的调用仍然是UTC时间,而不是{{1命令(正确的时间)。
我不想更改所有date
次呼叫 - 其中有数百次呼叫...这导致我的进程工作的时间与控制台上设置的正确时间不同。
有没有办法解决这个问题而不改变我的代码?我在这里找不到任何东西?
感谢您的帮助。
答案 0 :(得分:13)
虽然标准未指定,但std::chrono::system_clock::now()
的每个实施都在跟踪Unix Time,这与UTC非常接近。
如果您想将std::chrono::system_clock::now()
翻译为当地时间,可以通过system_clock::time_point
将time_t
翻译为system_clock::to_time_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
是一个工厂函数,它以zoned_time
支持的精度(例如纳秒)返回类型system_clock
。它是time_zone
和system_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';
虽然该库具有自动下载IANA timezone database的远程API,但可以通过使用-DHAS_REMOTE_API=0
进行编译来禁用该API。这一点在installation instructions中有详细说明。禁用远程API后,您必须从IANA timezone database手动下载数据库(它只是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"
来打印offset
。 offset
的类型为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