Alternative timegm for Solaris

I have a program that was originally written for Linux, but now I have a requirement to get it working on Solaris 10.

Part of this program uses the timegm function to convert a value struct tmto a second value time_t. Input time refers to UTC.

Trying to compile this program on Solaris, it fails because it timegmcannot be found. After some googling, I realized that this feature was removed from Solaris a long time ago (and even the Linux help system recommends not using it because it is not standardized).

However, I have not yet been able to find an alternative function that accepts struct tm, to which UTC refers, and transforms into an era. Most of the links that I found on the network recommend using mktime , however this function interprets inputs with a link to the local time zone of the system.

Please note that I do not want to use tzsetto force the time zone for UTC, as this will have other side effects for the program.

So my question is: how can I convert the struct tmstakeout time expressed in terms of UTC to an era in the absence timegm?

The program is written in C ++, so I am not limited to C-solutions, although I would prefer not to start wholesale processing to use an additional time library.

+4
2

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

{year, month, day} tm (1970-01-01). tm (, tm_year + 1900).

86400 {, , } tm ( ).

. , timegm . , ++ 11/14, , , , .

++ 14, . C ( , ).

+5

Per POSIX tzset():

#include <time.h>

extern int daylight;
extern long timezone;

extern char *tzname[2];
void tzset(void);

...

tzset() 0, ; , . timezone ​​ (UTC) .

tzset(), timezone, mktime(), , timezone mktime(), UTC.

Solaris , .

0

Source: https://habr.com/ru/post/1662493/


All Articles