]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
add utc to time_t
authorAlan T. DeKok <aland@freeradius.org>
Tue, 4 Aug 2020 16:16:06 +0000 (12:16 -0400)
committerAlan T. DeKok <aland@freeradius.org>
Tue, 4 Aug 2020 16:54:44 +0000 (12:54 -0400)
which is significantly faster than timegm() in OSX.  That function
takes a lock to get time zone information, which we don't need.

src/lib/util/time.c
src/lib/util/time.h

index b811a314b8bac561ae798a0e29046041193896f8..cd42edff97de06a0d028cfd13568f656b8081ffb 100644 (file)
@@ -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;
+}
index c69dc0206b120c1f7b6c6c4dc97a854c151c6fcb..7bc17cd1b741bbe34f58a464d9298d158e7d45a7 100644 (file)
@@ -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
 }