"Fossies" - the Fresh Open Source Software Archive

Member "dateutils-0.4.6/lib/gmtime.h" (19 Mar 2019, 2379 Bytes) of package /linux/privat/dateutils-0.4.6.tar.xz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "gmtime.h" see the Fossies "Dox" file reference documentation.

    1 /* metaprogramming */
    2 #if !defined INCLUDED_gmtime_h_
    3 #define INCLUDED_gmtime_h_
    4 #include <stdint.h>
    5 
    6 /* UTC has a constant day length */
    7 #define UTC_SECS_PER_DAY    (86400)
    8 
    9 static void
   10 ffff_gmtime(struct tm *tm, const time_t t)
   11 {
   12     static uint16_t __mon_yday[] = {
   13         /* this is \sum ml,
   14          * first element is a bit set of leap days to add */
   15         0xfff8, 0,
   16         31, 59, 90, 120, 151, 181,
   17         212, 243, 273, 304, 334, 365
   18     };
   19     register int days;
   20     register unsigned int yy;
   21     const uint16_t *ip;
   22 #if defined FFFF_GMTIME_SUBDAY
   23     int secs;
   24 #endif  /* FFFF_GMTIME_SUBDAY */
   25 
   26     /* just go to day computation */
   27     days = (int)(t / UTC_SECS_PER_DAY);
   28 #if defined FFFF_GMTIME_SUBDAY
   29     secs = (int)(t % UTC_SECS_PER_DAY);
   30 #endif  /* FFFF_GMTIME_SUBDAY */
   31     /* week day computation, that one's easy, 1 jan '70 was Thu */
   32     tm->tm_wday = (days + 4) % GREG_DAYS_P_WEEK;
   33 
   34     /* gotta do the date now */
   35     yy = 1970;
   36     /* stolen from libc */
   37 #define DIV(a, b)       ((a) / (b))
   38 /* we only care about 1901 to 2099 and there are no bullshit leap years */
   39 #define LEAPS_TILL(y)       (DIV(y, 4))
   40     while (days < 0 || days >= (!__leapp(yy) ? 365 : 366)) {
   41         /* Guess a corrected year, assuming 365 days per year. */
   42         register unsigned int yg = yy + days / 365 - (days % 365 < 0);
   43 
   44         /* Adjust DAYS and Y to match the guessed year.  */
   45         days -= (yg - yy) * 365 +
   46             LEAPS_TILL(yg - 1) - LEAPS_TILL(yy - 1);
   47         yy = yg;
   48     }
   49     /* set the year */
   50     tm->tm_year = (int)yy;
   51 
   52     ip = __mon_yday;
   53     /* unrolled */
   54     yy = 13;
   55     if (days < ip[--yy] &&
   56         days < ip[--yy] &&
   57         days < ip[--yy] &&
   58         days < ip[--yy] &&
   59         days < ip[--yy] &&
   60         days < ip[--yy] &&
   61         days < ip[--yy] &&
   62         days < ip[--yy] &&
   63         days < ip[--yy] &&
   64         days < ip[--yy] &&
   65         days < ip[--yy]) {
   66         yy = 1;
   67     }
   68     /* set the rest of the tm structure */
   69     tm->tm_mday = days - ip[yy] + 1;
   70     tm->tm_yday = days;
   71     tm->tm_mon = (int)yy;
   72     /* fix up leap years */
   73     if (UNLIKELY(__leapp(tm->tm_year))) {
   74         if ((ip[0] >> (yy)) & 1) {
   75             if (UNLIKELY(tm->tm_yday == 59)) {
   76                 tm->tm_mon = 2;
   77                 tm->tm_mday = 29;
   78             } else if (UNLIKELY(tm->tm_yday == ip[yy])) {
   79                 tm->tm_mday = tm->tm_yday - ip[--tm->tm_mon];
   80             } else {
   81                 tm->tm_mday--;
   82             }
   83         }
   84     }
   85 #if defined FFFF_GMTIME_SUBDAY
   86     tm->tm_sec = secs % 60U;
   87     secs /= 60U;
   88     tm->tm_min = secs % 60U;
   89     secs /= 60U;
   90     tm->tm_hour = secs;
   91 #endif  /* FFFF_GMTIME_SUBDAY */
   92     return;
   93 }
   94 
   95 #endif  /* INCLUDED_gmtime_h_ */