使用boost :: chrono,如何从单独的年,月,日,小时,分钟,秒开始计算自纪元UTC以来的毫秒数

use*_*025 1 c++ boost c++-chrono

我获得了UTC中年,月,日,小时,分钟和秒的值.我需要计算自纪元(UTC)以来的毫秒数.

怎么能实现这一目标?

谢谢

How*_*ant 5

如果你可以忽略闰秒,使用正确的工具很容易.

你会需要:

  1. days_from_civil位于这里.
  2. duration表示天= = 24小时的自定义类型(如下所示).
  3. C++ 11 std::chronoboost::chrono库(我正在展示它std::chrono).

以下是创建chrono::duration24小时自定义的方法:

typedef std::chrono::duration
<
    std::int32_t, std::ratio_multiply<std::chrono::hours::period, std::ratio<24>>
> days;
Run Code Online (Sandbox Code Playgroud)

现在您已准备好编写函数:

std::chrono::milliseconds
ms_since_UTC(int year, int month, int day, std::chrono::hours h,
             std::chrono::minutes m, std::chrono::seconds s)
{
    return days(days_from_civil(year, month, day)) + h + m + s;
}
Run Code Online (Sandbox Code Playgroud)

days_from_civil将您year/month/day转换为自1970年新世纪(UTC时代)以来的天数.您的自定义duration days将无缝地与"预先定义的"计时持续时间互操作:hours,minutes,seconds,和milliseconds.所有这些持续时间将隐式转换为milliseconds没有截断错误.

如果您需要考虑闰秒,那么您将需要构建一个表{days, chrono::seconds},其中条目的第二部分是您需要添加到持续时间的累计闰秒数,如果当前值为dayson或after该days表中的条目.

static constexpr std::pair<days, std::chrono::seconds> leap_seconds[25] =
{
    std::make_pair(days(days_from_civil(1972, 7, 1)), std::chrono::seconds(1)),
    // ...
};
Run Code Online (Sandbox Code Playgroud)

然后,您将需要搜索该表(使用std::find_if,或std::lower_bound)以查看从days_from_civil表之前,表内或表之外的返回.如果在表格之前添加0闰秒.如果在表中,则根据表条目添加适当数量的闰秒.如果超出表格,则添加(当前)25闰秒.

return d + h + m + s + ls;
Run Code Online (Sandbox Code Playgroud)

这是一种"高维护"解决方案,因为每次决定向UTC添加闰秒时,都需要更新此代码中的表.还应该注意的是,该解决方案在未来超过大约6个月不能高可信地使用,因为人们根本不知道将来是否会进一步增加(或减去)闰秒.

days_from_civil代码是在公共领域,可以随意使用它.它很有效率.当给出32位有符号输入时,它具有大约580万年的+/-范围(因此您不必担心会破坏其有效范围). 如果您感兴趣,本文将详细介绍算法的工作原理.