LCOV - code coverage report
Current view: top level - lib/libc/minimal/source/time - gmtime.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 0 29 0.0 %
Date: 2022-08-18 11:36:24 Functions: 0 1 0.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 16 0.0 %

           Branch data     Line data    Source code
       1                 :            : /*
       2                 :            :  * Copyright (c) 2019 Peter Bigot Consulting, LLC
       3                 :            :  *
       4                 :            :  * SPDX-License-Identifier: Apache-2.0
       5                 :            :  */
       6                 :            : 
       7                 :            : /*
       8                 :            :  * The time_civil_from_days function is derived directly from public
       9                 :            :  * domain content written by Howard Hinnant and available at:
      10                 :            :  * http://howardhinnant.github.io/date_algorithms.html#civil_from_days
      11                 :            :  */
      12                 :            : 
      13                 :            : #include <time.h>
      14                 :            : 
      15                 :            : /* A signed type with the representation of time_t without its
      16                 :            :  * implications.
      17                 :            :  */
      18                 :            : typedef time_t bigint_type;
      19                 :            : 
      20                 :            : /** Convert a UNIX time to civil time.
      21                 :            :  *
      22                 :            :  * This converts integral seconds since (before) 1970-01-01T00:00:00
      23                 :            :  * to the POSIX standard civil time representation.  Any adjustments
      24                 :            :  * due to time zone, leap seconds, or a different epoch must be
      25                 :            :  * applied to @p time before invoking this function.
      26                 :            :  *
      27                 :            :  * @param time the time represented as seconds.
      28                 :            :  *
      29                 :            :  * @return the time information for corresponding to the provided
      30                 :            :  * instant.
      31                 :            :  *
      32                 :            :  * @see http://howardhinnant.github.io/date_algorithms.html#civil_from_days
      33                 :            :  */
      34                 :          0 : static void time_civil_from_days(bigint_type z,
      35                 :            :                                  struct tm *ZRESTRICT tp)
      36                 :            : {
      37         [ #  # ]:          0 :         tp->tm_wday = (z >= -4) ? ((z + 4) % 7) : ((z + 5) % 7 + 6);
      38                 :          0 :         z += 719468;
      39                 :            : 
      40         [ #  # ]:          0 :         bigint_type era = ((z >= 0) ? z : (z - 146096)) / 146097;
      41                 :          0 :         unsigned int doe = (z - era * (bigint_type)146097);
      42                 :          0 :         unsigned int yoe = (doe - doe / 1460U + doe / 36524U - doe / 146096U)
      43                 :            :                 / 365U;
      44                 :          0 :         bigint_type y = (time_t)yoe + era * 400;
      45                 :          0 :         unsigned int doy = doe - (365U * yoe + yoe / 4U - yoe / 100U);
      46                 :          0 :         unsigned int mp = (5U * doy + 2U) / 153U;
      47                 :          0 :         unsigned int d = doy - (153U * mp + 2U) / 5U + 1U;
      48         [ #  # ]:          0 :         unsigned int m = mp + ((mp < 10) ? 3 : -9);
      49                 :            : 
      50                 :          0 :         tp->tm_year = y + (m <= 2) - 1900;
      51                 :          0 :         tp->tm_mon = m - 1;
      52                 :          0 :         tp->tm_mday = d;
      53                 :            : 
      54                 :            :         /* Everything above is explained on the referenced page, but
      55                 :            :          * doy is relative to --03-01 and we need it relative to
      56                 :            :          * --01-01.
      57                 :            :          *
      58                 :            :          * doy=306 corresponds to --01-01, doy=364 to --02-28, and
      59                 :            :          * doy=365 to --02-29.  So we can just subtract 306 to handle
      60                 :            :          * January and February.
      61                 :            :          *
      62                 :            :          * For doy<306 we have to add the number of days before
      63                 :            :          * --03-01, which is 59 in a common year and 60 in a leap
      64                 :            :          * year.  Note that the first year in the era is a leap year.
      65                 :            :          */
      66         [ #  # ]:          0 :         if (doy >= 306U) {
      67                 :          0 :                 tp->tm_yday = doy - 306U;
      68                 :            :         } else {
      69   [ #  #  #  #  :          0 :                 tp->tm_yday = doy + 59U + (((yoe % 4U == 0U) && (yoe % 100U != 0U)) || (yoe == 0U));
                   #  # ]
      70                 :            :         }
      71                 :          0 : }
      72                 :            : 
      73                 :            : /* Convert a UNIX time to civil time.
      74                 :            :  *
      75                 :            :  * This converts integral seconds since (before) 1970-01-01T00:00:00
      76                 :            :  * to the POSIX standard civil time representation.  Any adjustments
      77                 :            :  * due to time zone, leap seconds, or a different epoch must be
      78                 :            :  * applied to @p time before invoking this function.
      79                 :            :  */
      80                 :            : struct tm *gmtime_r(const time_t *ZRESTRICT timep,
      81                 :            :                     struct tm *ZRESTRICT result)
      82                 :            : {
      83                 :          0 :         time_t z = *timep;
      84         [ #  # ]:          0 :         bigint_type days = (z >= 0 ? z : z - 86399) / 86400;
      85                 :          0 :         unsigned int rem = z - days * 86400;
      86                 :            : 
      87                 :          0 :         *result = (struct tm){ 0 };
      88                 :            : 
      89                 :          0 :         time_civil_from_days(days, result);
      90                 :            : 
      91                 :          0 :         result->tm_hour = rem / 60U / 60U;
      92                 :          0 :         rem -= result->tm_hour * 60 * 60;
      93                 :          0 :         result->tm_min = rem / 60;
      94                 :          0 :         result->tm_sec = rem - result->tm_min * 60;
      95                 :            : 
      96                 :          0 :         return result;
      97                 :            : }
      98                 :            : 
      99                 :            : struct tm *gmtime(const time_t *timep)
     100                 :            : {
     101                 :            :         static struct tm shared;
     102                 :            : 
     103                 :          0 :         return gmtime_r(timep, &shared);
     104                 :            : }

Generated by: LCOV version 1.14