替代Solaris上的timegm

har*_*mic 5 c++ solaris solaris-10

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

该程序的一部分使用timegm函数将a struct tm转换为time_tepoch秒值.输入时间以UTC为参考.

尝试在Solaris上编译此程序,它失败,因为timegm找不到.经过一些谷歌搜索后,我意识到很久以前这个功能已经从Solaris中删除了(甚至Linux手册也建议不要使用它,因为它没有标准化).

但是到目前为止,我还没有找到一个替代函数,它接受struct tmUTC参考并转换为纪元时间.我在网上找到的大多数参考建议使用mktime,但该函数会参考系统本地时区来解释输入.

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

所以我的问题是:struct tm在没有timegm?的情况下,如何将一个相对于UTC表示的故障时间值转换为一个纪元时间?

该程序是用C++编写的,所以我不仅限于C解决方案,尽管我不想开始批量重写以使用一些额外的时间库.

How*_*ant 5

你可以使用days_from_civil进行详细描述

// 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;
}
Run Code Online (Sandbox Code Playgroud)

将{年,月,日}三联转换为tm自纪元(1970-01-01)以来的天数.从转换这些字段时要小心tm它们的偏心率(例如tm_year + 1900).

将此天数乘以86400,并将(小时,分钟,秒)数据添加到tm(每个转换为秒数).

而且你已经完成了.不要担心闰秒,timegm也不要担心它们.如果你真的关心闰秒我有一个C++ 11/14解决方案可以解决这个问题,但我猜这比你想要的更多.

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

  • 好一个.您的日期算法页面是一个很棒的资源 (3认同)