LCOV - code coverage report
Current view: top level - libs/rational/src - rational_time.c (source / functions) Coverage Total Hit
Test: coverage.info Lines: 90.4 % 104 94
Test Date: 2026-03-31 13:51:38 Functions: 85.7 % 7 6
Branches: 78.9 % 38 30

             Branch data     Line data    Source code
       1                 :             : #include "rational.h"
       2                 :             : 
       3                 :             : /**
       4                 :             :  * @brief Current time in milliseconds
       5                 :             :  * @return Returns long long int the number of milliseconds since the UNIX epoch
       6                 :             :  */
       7                 :           0 : long long int cur_time_ms(void)
       8                 :             : {
       9                 :             :         struct timeval t;
      10                 :           0 :         gettimeofday(&t,NULL);
      11                 :           0 :         long long mt = (long long)t.tv_sec * 1000 + t.tv_usec / 1000;
      12                 :           0 :         return(mt);
      13                 :             : }
      14                 :             : 
      15                 :             : /**
      16                 :             :  * @brief Current time in nanoseconds
      17                 :             :  * @return long long int number of nanoseconds, count starts at the Unix Epoch on January 1st, 1970 at UTC
      18                 :             :  * @details Source: https://stackoverflow.com/questions/39439268/printing-time-since-epoch-in-nanoseconds
      19                 :             :  */
      20                 :         522 : long long int cur_time_ns(void)
      21                 :             : {
      22                 :             :         long long int ns;
      23                 :             :         time_t sec;
      24                 :             :         struct timespec spec;
      25                 :         522 :         clock_gettime(CLOCK_REALTIME,&spec);
      26                 :         522 :         sec = spec.tv_sec;
      27                 :         522 :         ns = spec.tv_nsec;
      28                 :         522 :         return(((long long int)sec * 1000000000LL) + ns);
      29                 :             : }
      30                 :             : 
      31                 :             : /**
      32                 :             :  * @brief Current monotonic time in nanoseconds
      33                 :             :  * @return long long int number of nanoseconds from a monotonic clock source
      34                 :             :  * @details Counter starts at an unspecified point and is intended for interval measurement.
      35                 :             :  * Unlike CLOCK_REALTIME, this source is not affected by wall-clock adjustments.
      36                 :             :  */
      37                 :             : #if defined(CLOCK_MONOTONIC) && (!defined(_POSIX_MONOTONIC_CLOCK) || (_POSIX_MONOTONIC_CLOCK >= 0))
      38                 :        4692 : long long int cur_time_monotonic_ns(void)
      39                 :             : {
      40                 :             :         long long int ns;
      41                 :             :         time_t sec;
      42                 :             :         struct timespec spec;
      43                 :        4692 :         clock_gettime(CLOCK_MONOTONIC,&spec);
      44                 :        4692 :         sec = spec.tv_sec;
      45                 :        4692 :         ns = spec.tv_nsec;
      46                 :        4692 :         return(((long long int)sec * 1000000000LL) + ns);
      47                 :             : }
      48                 :             : #endif
      49                 :             : 
      50                 :             : /**
      51                 :             :  *
      52                 :             :  * @brief Convert from UNIXtime seconds to ISO datetimes
      53                 :             :  * @param seconds - if a parameter is passed in the form of milliseconds,
      54                 :             :  * then exactly the specified time will be converted to ISO format.
      55                 :             :  * If 0 is passed, the current time will be printed out in ISO format.
      56                 :             :  *
      57                 :             :  */
      58                 :         320 : char *seconds_to_ISOdate(time_t seconds)
      59                 :             : {
      60                 :             :         struct timeval curTime;
      61                 :         320 :         gettimeofday(&curTime,NULL);
      62                 :             : 
      63                 :             :         // String to store converted time
      64                 :             :         static char str_t[sizeof "2011-10-18 07:07:09"] = "";
      65                 :         320 :         str_t[0] = '\0';  /* Initialize buffer as empty string */
      66                 :             : 
      67                 :             :         // Pointer to a structure with local time
      68                 :             :         struct tm cur_time;
      69                 :             : 
      70                 :             :         // Convert system time to local time
      71                 :         320 :         localtime_r(&seconds,&cur_time);
      72                 :             : 
      73                 :             :         // Create a string with date and time accurate to seconds
      74                 :         320 :         strftime(str_t,sizeof(str_t),"%Y-%m-%d %H:%M:%S",&cur_time);
      75                 :             : 
      76                 :             :         #if 0
      77                 :             :         printf("current time: %s \n",str_t);
      78                 :             :         #endif
      79                 :             : 
      80                 :         320 :         return(str_t);
      81                 :             : }
      82                 :             : 
      83                 :             : /**
      84                 :             :  *
      85                 :             :  * @brief "As a date", Convert nanoseconds to date format
      86                 :             :  *
      87                 :             :  */
      88                 :             : __attribute__((always_inline)) static inline Date asadate(const long long int nanoseconds)
      89                 :             : {
      90                 :             :         /// Number of nanoseconds in a year
      91                 :             :         /// 365*24*60*60*1000*1000*1000
      92                 :         608 :         const long long int ns_in_year = 31536000000000000LL;
      93                 :             : 
      94                 :             :         /// Number of nanoseconds in a month
      95                 :             :         /// ns_in_year/12
      96                 :         608 :         const long long int ns_in_month = 2628000000000000LL;
      97                 :             : 
      98                 :             :         /// Number of nanoseconds in a week
      99                 :             :         /// 7*24*60*60*1000*1000*1000
     100                 :         608 :         const long long int ns_in_week = 604800000000000LL;
     101                 :             : 
     102                 :             :         /// Number of nanoseconds in a day
     103                 :             :         /// 24*60*60*1000*1000*1000
     104                 :         608 :         const long long int ns_in_day = 86400000000000LL;
     105                 :             : 
     106                 :             :         /// Number of nanoseconds in an hour
     107                 :             :         /// 60*60*1000*1000*1000
     108                 :         608 :         const long long int ns_in_hour = 3600000000000LL;
     109                 :             : 
     110                 :             :         /// Number of nanoseconds in a minute
     111                 :             :         /// 60*1000*1000*1000
     112                 :         608 :         const long long int ns_in_minute = 60000000000LL;
     113                 :             : 
     114                 :             :         /// Number of nanoseconds in a second
     115                 :             :         /// 1000*1000*1000
     116                 :         608 :         const long long int ns_in_second = 1000000000LL;
     117                 :             : 
     118                 :             :         /// Number of nanoseconds in a millisecond
     119                 :             :         /// 1000*1000
     120                 :         608 :         const long long int ns_in_millisecond = 1000000LL;
     121                 :             : 
     122                 :             :         /// Number of nanoseconds in a microsecond
     123                 :             :         /// 1000
     124                 :         608 :         const long long int ns_in_microsecond = 1000LL;
     125                 :             : 
     126                 :             :         // Initializing the structure that will be returned from the function
     127                 :         608 :         Date date = {0};
     128                 :             : 
     129                 :         608 :         date.years = nanoseconds/ns_in_year;
     130                 :             : 
     131                 :         608 :         const long long int years_ns = date.years * ns_in_year;
     132                 :         608 :         date.months = (nanoseconds - years_ns)/ns_in_month;
     133                 :             : 
     134                 :         608 :         const long long int months_ns = date.months * ns_in_month;
     135                 :         608 :         date.weeks = (nanoseconds - years_ns - months_ns)/ns_in_week;
     136                 :             : 
     137                 :         608 :         const long long int weeks_ns = date.weeks * ns_in_week;
     138                 :         608 :         date.days = (nanoseconds - years_ns - months_ns - weeks_ns)/ns_in_day;
     139                 :             : 
     140                 :         608 :         const long long int days_ns = date.days * ns_in_day;
     141                 :         608 :         date.hours = (nanoseconds - years_ns - months_ns - weeks_ns - days_ns)/ns_in_hour;
     142                 :             : 
     143                 :         608 :         const long long int hours_ns = date.hours * ns_in_hour;
     144                 :         608 :         date.minutes = (nanoseconds - years_ns - months_ns - weeks_ns - days_ns - hours_ns)/ns_in_minute;
     145                 :             : 
     146                 :         608 :         const long long int minutes_ns = date.minutes * ns_in_minute;
     147                 :         608 :         date.seconds = (nanoseconds - years_ns - months_ns - weeks_ns - days_ns - hours_ns - minutes_ns)/ns_in_second;
     148                 :             : 
     149                 :         608 :         const long long int seconds_ns = date.seconds * ns_in_second;
     150                 :         608 :         date.milliseconds = (nanoseconds - years_ns - months_ns - weeks_ns - days_ns - hours_ns - minutes_ns - seconds_ns)/ns_in_millisecond;
     151                 :             : 
     152                 :         608 :         const long long int milliseconds_ns = date.milliseconds * ns_in_millisecond;
     153                 :         608 :         date.microseconds = (nanoseconds - years_ns - months_ns - weeks_ns - days_ns - hours_ns - minutes_ns - seconds_ns - milliseconds_ns)/ns_in_microsecond;
     154                 :             : 
     155                 :         608 :         const long long int microseconds_ns = date.microseconds * ns_in_microsecond;
     156                 :         608 :         date.nanoseconds = (nanoseconds - years_ns - months_ns - weeks_ns - days_ns - hours_ns - minutes_ns - seconds_ns - milliseconds_ns - microseconds_ns);
     157                 :             : 
     158                 :         608 :         return(date);
     159                 :             : }
     160                 :             : 
     161                 :             : /**
     162                 :             :  *
     163                 :             :  * The function for convert nanoseconds to a readable date. The function
     164                 :             :  * generates a string if the structure element contains time data greater
     165                 :             :  * than zero.
     166                 :             :  *
     167                 :             :  */
     168                 :        3713 : static void catdate_r(
     169                 :             :         char *const         result,
     170                 :             :         const size_t        result_size,
     171                 :             :         size_t *const       used_len,
     172                 :             :         const long long int number,
     173                 :             :         const char *const   suffix)
     174                 :             : {
     175   [ +  +  -  + ]:        3713 :         if(number <= 0LL || *used_len >= result_size)
     176                 :             :         {
     177                 :        2568 :                 return;
     178                 :             :         }
     179                 :             : 
     180                 :        1145 :         const int written = snprintf(result + *used_len,result_size - *used_len,"%lld%s ",number,suffix);
     181                 :             : 
     182         [ -  + ]:        1145 :         if(written < 0)
     183                 :             :         {
     184                 :           0 :                 return;
     185                 :             :         }
     186                 :             : 
     187                 :        1145 :         const size_t write_size = (size_t)written;
     188                 :             : 
     189         [ +  + ]:        1145 :         if(write_size >= result_size - *used_len)
     190                 :             :         {
     191                 :           2 :                 *used_len = result_size - 1ULL;
     192                 :           2 :                 result[result_size - 1ULL] = '\0';
     193                 :             :         } else {
     194                 :        1143 :                 *used_len += write_size;
     195                 :             :         }
     196                 :             : }
     197                 :             : 
     198                 :             : /**
     199                 :             :  *
     200                 :             :  * Convert nanoseconds to human-readable date as a string
     201                 :             :  *
     202                 :             :  */
     203                 :         644 : char *form_date_r(
     204                 :             :         const long long int nanoseconds,
     205                 :             :         const ByteFormat    format,
     206                 :             :         char                *buffer,
     207                 :             :         const size_t        buffer_size)
     208                 :             : {
     209   [ +  +  +  + ]:         644 :         if(buffer == NULL || buffer_size == 0ULL)
     210                 :             :         {
     211                 :           2 :                 return(NULL);
     212                 :             :         }
     213                 :             : 
     214                 :         642 :         buffer[0] = '\0';  /* Initialize buffer as empty string */
     215                 :         642 :         size_t used_len = 0ULL;
     216                 :             : 
     217                 :             :         // If the time passed as argument is less than one nanosecond
     218         [ +  + ]:         642 :         if(nanoseconds == 0LL)
     219                 :             :         {
     220                 :          34 :                 (void)snprintf(buffer,buffer_size,"0ns");
     221                 :          34 :                 return(buffer);
     222                 :             :         }
     223                 :             : 
     224                 :             :         Date date = asadate(nanoseconds);
     225                 :             : 
     226         [ +  + ]:         608 :         if(format == MAJOR_VIEW)
     227                 :             :         {
     228         [ -  + ]:         263 :                 if(date.years > 0LL)
     229                 :             :                 {
     230                 :           0 :                         catdate_r(buffer,buffer_size,&used_len,date.years,"y");
     231         [ -  + ]:         263 :                 } else if(date.months > 0LL){
     232                 :           0 :                         catdate_r(buffer,buffer_size,&used_len,date.months,"mon");
     233         [ -  + ]:         263 :                 } else if(date.weeks > 0LL){
     234                 :           0 :                         catdate_r(buffer,buffer_size,&used_len,date.weeks,"w");
     235         [ -  + ]:         263 :                 } else if(date.days > 0LL){
     236                 :           0 :                         catdate_r(buffer,buffer_size,&used_len,date.days,"d");
     237         [ +  + ]:         263 :                 } else if(date.hours > 0LL){
     238                 :           1 :                         catdate_r(buffer,buffer_size,&used_len,date.hours,"h");
     239         [ -  + ]:         262 :                 } else if(date.minutes > 0LL){
     240                 :           0 :                         catdate_r(buffer,buffer_size,&used_len,date.minutes,"min");
     241         [ +  + ]:         262 :                 } else if(date.seconds > 0LL){
     242                 :           7 :                         catdate_r(buffer,buffer_size,&used_len,date.seconds,"s");
     243         [ +  + ]:         255 :                 } else if(date.milliseconds > 0LL){
     244                 :         200 :                         catdate_r(buffer,buffer_size,&used_len,date.milliseconds,"ms");
     245         [ +  + ]:          55 :                 } else if(date.microseconds > 0LL){
     246                 :          50 :                         catdate_r(buffer,buffer_size,&used_len,date.microseconds,"μs");
     247                 :             :                 } else {
     248                 :           5 :                         catdate_r(buffer,buffer_size,&used_len,date.nanoseconds,"ns");
     249                 :             :                 }
     250                 :             :         } else {
     251                 :         345 :                 catdate_r(buffer,buffer_size,&used_len,date.years,"y");
     252                 :         345 :                 catdate_r(buffer,buffer_size,&used_len,date.months,"mon");
     253                 :         345 :                 catdate_r(buffer,buffer_size,&used_len,date.weeks,"w");
     254                 :         345 :                 catdate_r(buffer,buffer_size,&used_len,date.days,"d");
     255                 :         345 :                 catdate_r(buffer,buffer_size,&used_len,date.hours,"h");
     256                 :         345 :                 catdate_r(buffer,buffer_size,&used_len,date.minutes,"min");
     257                 :         345 :                 catdate_r(buffer,buffer_size,&used_len,date.seconds,"s");
     258                 :         345 :                 catdate_r(buffer,buffer_size,&used_len,date.milliseconds,"ms");
     259                 :         345 :                 catdate_r(buffer,buffer_size,&used_len,date.microseconds,"μs");
     260                 :         345 :                 catdate_r(buffer,buffer_size,&used_len,date.nanoseconds,"ns");
     261                 :             :         }
     262                 :             : 
     263                 :             :         // Remove trailing space at the end of the line.
     264   [ +  +  +  - ]:         608 :         if(used_len > 0ULL && buffer[used_len - 1ULL] == ' ')
     265                 :             :         {
     266                 :         607 :                 buffer[used_len - 1ULL] = '\0';
     267                 :             :         }
     268                 :             : 
     269                 :         608 :         return(buffer);
     270                 :             : }
     271                 :             : 
     272                 :             : /**
     273                 :             :  *
     274                 :             :  * Convert nanoseconds to human-readable date as a string
     275                 :             :  *
     276                 :             :  */
     277                 :         267 : char *form_date(
     278                 :             :         const long long int nanoseconds,
     279                 :             :         const ByteFormat    format)
     280                 :             : {
     281                 :             :         // Zero out a static memory area with a string array
     282                 :             :         static char result[MAX_CHARACTERS];
     283                 :             : 
     284                 :         267 :         return(form_date_r(nanoseconds,format,result,sizeof(result)));
     285                 :             : }
     286                 :             : #if 0
     287                 :             : /// Test
     288                 :             : 
     289                 :             : /// To build
     290                 :             : /// gcc -I../../logger/lib/ time.c
     291                 :             : 
     292                 :             : /// 339800645368118513 = ((365*24*60*60*1000*1000*1000)*10) + (((365*24*60*60*1000*1000*1000)/12)*9)+((7*24*60*60*1000*1000*1000)*1)+((24*60*60*1000*1000*1000)*2)+((60*60*1000*1000*1000)*3)+((60*1000*1000*1000)*4)+((1000*1000*1000)*5)+((1000*1000)*368)+((1000)*118)+513
     293                 :             : /// Should be 10y 9mon 1w 2d 3h 4min 5s 368ms 118μs 513ns
     294                 :             : 
     295                 :             : int main(void)
     296                 :             : {
     297                 :             :         long long int ns = 339800645368118513LL;
     298                 :             :         printf("%s\n",form_date(ns,FULL_VIEW));
     299                 :             : 
     300                 :             :         printf("%s\n",form_date(273522528,FULL_VIEW));
     301                 :             : 
     302                 :             :         return 0;
     303                 :             : }
     304                 :             : #endif
        

Generated by: LCOV version 2.0-1