【问题标题】:C++: get time zone deviationC++:获取时区偏差
【发布时间】:2020-09-21 08:50:51
【问题描述】:

所以我想在 C++ 中创建一个格式为 HH:MM:SS 的时间戳(作为字符串)。我使用std::chrono 获取unix 时间戳,然后计算小时、分钟和秒。

// Get unix time stamp in seconds.
const auto unix_time_stamp = std::chrono::system_clock::now();
long long seconds_since_epoch = std::chrono::duration_cast<std::chrono::seconds>(unix_time_stamp.time_since_epoch()).count();

// Calculate current time (hours, minutes, seconds).
uint8_t hours = (seconds_since_epoch % 86400) / 3600;
uint8_t minutes = (seconds_since_epoch % 3600) / 60;
uint8_t seconds = (seconds_since_epoch % 60);

// Create strings for hours, minutes, seconds.
std::string hours_string = std::to_string(hours);
std::string minutes_string = std::to_string(minutes);
std::string seconds_string = std::to_string(seconds);

// Check if the number is only one digit. If it is, add a 0 in the beginning (5:3:9 --> 05:03:09).
if(hours_string.size() == 1)
{
  hours_string = "0" + hours_string;
}
if(minutes_string.size() == 1)
{
  minutes_string = "0" + minutes_string;
}
if(seconds_string.size() == 1)
{
  seconds_string = "0" + seconds_string;
}

// Append to a final string.
std::string time_stamp = hours_string + ":" + minutes_string + ":" + seconds_string;

这一切都很好,但有一个大问题:时区。 通过这种方式,我只计算 GMT 的时间戳。是否有任何简单、快速且最重要的是便携的方法可以在几秒、几分钟或几小时内获得系统时区的“偏移量”? “便携”是指独立于平台的。

请注意:我知道您可以使用std::strftime 等更轻松地完成所有这些操作,但我真的很想自己实现。

【问题讨论】:

    标签: c++ time timezone


    【解决方案1】:

    std::tm 的某些实现将包含一个成员,该成员具有本地偏移量作为成员。 ...但它不是便携式的。

    一个技巧是获取您的seconds_since_epoch,然后将其分配给std::time_t,或者首先将其类型设为std::time_t 而不是long long

    ...哦,等等,这不是很便携。一些平台仍然使用 32 位 time_t。但假设 64 位 time_t ...

    然后使用localtime 得到std::tm

    std::tm tm = *localtime(&seconds_since_epoch);
    

    这不是官方可移植的,因为不能保证 system_clocktime_t 具有相同的纪元。但实际上他们确实如此。

    现在从tm 中取出{year, month, day, hour, minute, second} 字段并计算“本地历元”。此计算的难点是将{year, month, day} 部分转换为天数。您可以使用here 中的days_from_civil 来有效地进行计算。执行此操作时,请务必考虑 tm_yeartm_mon 的奇怪偏移量。

    得到这个之后,然后从中减去seconds_since_epoch

     auto offset = local_epoch - seconds_since_epoch;
    

    这是您签名的 UTC 偏移量(以秒为单位)。正值位于本初子午线以东。


    在 C++20 中,这简化为:

    auto offset = std::chrono::current_zone()->get_info(system_clock::now()).offset;
    

    offset 将具有std::chrono::seconds 类型。

    您可以获得free, open-source preview of this here。它确实需要一些installation

    【讨论】:

    • Howard - 只想写个便条,说我继续对您在帮助社区和为 C++20 改进日期/时间/时区所做的努力印象深刻。谢谢。
    猜你喜欢
    • 2012-11-28
    • 2015-12-20
    • 2016-05-07
    • 1970-01-01
    • 1970-01-01
    • 2019-04-07
    • 1970-01-01
    • 1970-01-01
    • 2016-08-24
    相关资源
    最近更新 更多