1

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

如何做到这一点?

谢谢

4

1 回答 1

5

如果您可以忽略闰秒,那么使用正确的工具很容易做到这一点。

你会需要:

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

以下是创建chrono::duration代表 24 小时的自定义的方法:

typedef std::chrono::duration
<
    std::int32_t, std::ratio_multiply<std::chrono::hours::period, std::ratio<24>>
> days;

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

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;
}

days_from_civil会将您year/month/day转换为自 1970 年新年(UTC 纪元)以来的天数。您的自定义duration days将与“预定义”计时持续时间无缝互操作:hoursminutessecondsmilliseconds。所有这些持续时间都将隐式转换为milliseconds没有截断错误。

如果您需要考虑闰秒,那么您需要构建一个 的表{days, chrono::seconds},其中条目的第二部分是您需要添加到持续时间的累积闰秒数,如果当前值为dayson 或之后表中的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)),
    // ...
};

然后,您需要搜索该表(使用std::find_if、 或std::lower_bound)以查看返回值是否days_from_civil位于表之前、表内或表外。如果在表格之前添加 0 闰秒。如果在表格内,您可以根据表格条目添加适当的闰秒数。如果超出表格,则添加(当前)25 闰秒。

return d + h + m + s + ls;

这是一个“高维护”解决方案,因为每次他们决定向 UTC 添加闰秒时,都需要更新此代码中的表。还应该注意的是,这个解决方案不能在未来超过大约 6 个月的时间内使用,因为人们根本不知道未来是否会增加(或减少)闰秒。

days_from_civil代码在公共领域,因此请随意使用。它是有效的。当给定 32 位签名输入时,它的 +/- 范围约为 580 万年(因此您不必担心会超出其有效性范围)。 如果您有兴趣,本文将详细介绍该算法的工作原理。

于 2013-11-22T16:34:34.520 回答