gpt4 book ai didi

c++ - Solaris 上 timegm 的替代品

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:28:15 24 4
gpt4 key购买 nike

我有一个最初是为 Linux 编写的程序,但我现在需要让它在 Solaris 10 上运行。

该程序的一部分使用了 timegmstruct tm 转换为 time_t 纪元秒值的函数。输入时间以UTC为引用。

试图在 Solaris 上编译这个程序,它失败了,因为找不到 timegm。经过一些谷歌搜索后,我意识到这个函数很久以前就已经从 Solaris 中删除了(甚至 Linux 联机帮助页也建议不要使用它,因为它不是标准化的)。

但是到目前为止,我还没有找到替代函数,该函数采用引用 UTC 的 struct tm 并将其转换为纪元时间。我在网上找到的大多数引用资料都推荐使用 mktime ,但是该函数会引用系统本地时区来解释输入。

请注意,我不希望使用 tzset 将时区强制为 UTC,因为这会对程序产生其他副作用。

所以我的问题是:在没有 timegm 的情况下,如何将一个 struct tm 分解的时间值(以 UTC 表示)转换为纪元时间?

该程序是用 C++ 编写的,所以我不限于 C 解决方案,尽管我不希望开始大规模重写以使用一些额外的时间库。

最佳答案

您可以使用 days_from_civil,即 described here in detail

// Returns number of days since civil 1970-01-01.  Negative values indicate
// days prior to 1970-01-01.
// Preconditions: y-m-d represents a date in the civil (Gregorian) calendar
// m is in [1, 12]
// d is in [1, last_day_of_month(y, m)]
// y is "approximately" in
// [numeric_limits<Int>::min()/366, numeric_limits<Int>::max()/366]
// Exact range of validity is:
// [civil_from_days(numeric_limits<Int>::min()),
// civil_from_days(numeric_limits<Int>::max()-719468)]
template <class Int>
constexpr
Int
days_from_civil(Int y, unsigned m, unsigned d) noexcept
{
static_assert(std::numeric_limits<unsigned>::digits >= 18,
"This algorithm has not been ported to a 16 bit unsigned integer");
static_assert(std::numeric_limits<Int>::digits >= 20,
"This algorithm has not been ported to a 16 bit signed integer");
y -= m <= 2;
const Int era = (y >= 0 ? y : y-399) / 400;
const unsigned yoe = static_cast<unsigned>(y - era * 400); // [0, 399]
const unsigned doy = (153*(m + (m > 2 ? -3 : 9)) + 2)/5 + d-1; // [0, 365]
const unsigned doe = yoe * 365 + yoe/4 - yoe/100 + doy; // [0, 146096]
return era * 146097 + static_cast<Int>(doe) - 719468;
}

tm 中的 {year, month, day} 三元组转换为自纪元 (1970-01-01) 以来的天数。在将这些字段从 tm 转换为它们的偏心率时要小心(例如 tm_year + 1900)。

将此天数乘以 86400,然后加上来自 tm 的{小时、分钟、秒}数据(每个都转换为秒)。

你就完成了。不用担心闰秒,timegm 也不担心。如果你真的关心闰秒,我有一个 C++11/14 solution available to deal with that ,但我猜这比您想了解的要多。

不要被上面显示的 C++14 语法拖延。将此算法转换为 C(或任何其他语言)是微不足道的。

关于c++ - Solaris 上 timegm 的替代品,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40904201/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com