2016-09-01 268 views
2

我正在编程一个在BusyBox嵌入式linux上运行的C++代码。我的代码和它的库有几个调用std::chrono::system_clock::now()来获取当前时间。std :: chrono :: system_clock :: now()考虑操作系统配置的时区

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

现在我不得不设置我的linux留在不同的时区。然后,我做到了通过配置在框中/etc/profile

export TZ=UTC+3 

当我发出命令date,我得到了正确的控制台的时候,但我对std::chrono::system_clock::now() I'm电话仍然得到UTC时间,而不是时间显示在date命令中(正确的时间)。

我不想改变我所有的now()调用 - 其上有几百个调用...这导致我的进程在不同的时间工作,而不是在控制台上设置的正确时间。

有没有办法解决这个问题,而不改变我的代码?我在这里错过的任何东西?

感谢您的帮助。

+0

这将是在内部使用任何东西,但UTC是错误的。将其显示给人类用户时,将其转换为当地时间。节目与UTC完全一致,他们不关心我们的昼夜节律。 –

+0

n.m. - 从now()收集的数据然后使用int64格式存储在本地和云数据库中,并将它们上载到Web服务器。然后显示给最终用户....在存储到数据库之前,我需要在我的C++代码上获得正确的时间,因为我将不会跟踪上述图层中的时区... – Mendes

+0

@mendes哦上帝不,不要将本地时间存储在云数据库中。 *可能*存储用户设置某个事件时使用的时区*旁边的通用时间戳(对于日历应用程序,他们选择了8月12日和7日),但本地时间几乎适用于每个用户输入和输出。这种情况(选择时区)是用户*在某种意义上(而不是某个时间,某个实际事件发生或“从现在起6小时”)选择绝对时间点*的时间。 – Yakk

回答

6

尽管标准没有指定,但std::chrono::system_clock::now()的每个实现都跟踪Unix Time,这与UTC非常接近。

如果你想std::chrono::system_clock::now()转换为本地时间,您可以通过system_clock::to_time_t翻译system_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是一种工厂功能,它返回zoned_time类型的任何精度,您的system_clock支持(例如,纳秒)。它是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 timezone database,该API可以通过与-DHAS_REMOTE_API=0编制被禁用。详情请见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"打印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 
+0

嗯,我不需要一个字符串,但与原来的现在(),但与时钟代表正确的时区相同的格式。在图书馆需要外部访问的情况下,嵌入式系统上没有互联网连接... – Mendes

+0

@Mendes:更新了解决您的问题的答案。 –

相关问题