From: Alan T. DeKok Date: Tue, 4 Aug 2020 16:16:06 +0000 (-0400) Subject: add utc to time_t X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e1b263baf257dd91e5baed429d46db3bb5ccaf87;p=thirdparty%2Ffreeradius-server.git add utc to time_t which is significantly faster than timegm() in OSX. That function takes a lock to get time zone information, which we don't need. --- diff --git a/src/lib/util/time.c b/src/lib/util/time.c index b811a314b8b..cd42edff97d 100644 --- a/src/lib/util/time.c +++ b/src/lib/util/time.c @@ -627,3 +627,23 @@ void fr_time_elapsed_fprint(FILE *fp, fr_time_elapsed_t const *elapsed, char con } } } + +/* + * Based on https://blog.reverberate.org/2020/05/12/optimizing-date-algorithms.html + */ +time_t fr_utc_to_time(struct tm *tm) +{ + static const uint16_t month_yday[12] = {0, 31, 59, 90, 120, 151, + 181, 212, 243, 273, 304, 334}; + + uint32_t year_adj = tm->tm_year + 4800 + 1900; /* Ensure positive year, multiple of 400. */ + uint32_t febs = year_adj - (tm->tm_mon <= 2 ? 1 : 0); /* Februaries since base. */ + uint32_t leap_days = 1 + (febs / 4) - (febs / 100) + (febs / 400); + uint32_t days = 365 * year_adj + leap_days + month_yday[tm->tm_mon] + tm->tm_mday - 1; + + /* + * 2472692 adjusts the days for Unix epoch. It is calculated as + * (365.2425 * (4800 + 1970)) + */ + return (days - 2472692) * 86400 + (tm->tm_hour * 3600) + (tm->tm_min * 60) + tm->tm_sec; +} diff --git a/src/lib/util/time.h b/src/lib/util/time.h index c69dc0206b1..7bc17cd1b74 100644 --- a/src/lib/util/time.h +++ b/src/lib/util/time.h @@ -207,6 +207,7 @@ size_t fr_time_strftime_utc(fr_sbuff_t *out, fr_time_t time, char const *fmt) void fr_time_elapsed_update(fr_time_elapsed_t *elapsed, fr_time_t start, fr_time_t end) CC_HINT(nonnull); void fr_time_elapsed_fprint(FILE *fp, fr_time_elapsed_t const *elapsed, char const *prefix, int tabs) CC_HINT(nonnull(1,2)); +time_t fr_utc_to_time(struct tm *tm) CC_HINT(nonnull); #ifdef __cplusplus }