LCOV - code coverage report
Current view: top level - libs/rational/src - rational_time.c (source / functions) Coverage Total Hit
Test: coverage.info Lines: 89.6 % 106 95
Test Date: 2026-03-01 04:31:48 Functions: 85.7 % 7 6
Branches: 77.5 % 40 31

             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                 :         476 : long long int cur_time_ns(void)
      21                 :             : {
      22                 :             :         long long int ns;
      23                 :             :         time_t sec;
      24                 :             :         struct timespec spec;
      25                 :         476 :         clock_gettime(CLOCK_REALTIME,&spec);
      26                 :         476 :         sec = spec.tv_sec;
      27                 :         476 :         ns = spec.tv_nsec;
      28                 :         476 :         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                 :        3778 : long long int cur_time_monotonic_ns(void)
      39                 :             : {
      40                 :             :         long long int ns;
      41                 :             :         time_t sec;
      42                 :             :         struct timespec spec;
      43                 :        3778 :         clock_gettime(CLOCK_MONOTONIC,&spec);
      44                 :        3778 :         sec = spec.tv_sec;
      45                 :        3778 :         ns = spec.tv_nsec;
      46                 :        3778 :         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                 :         569 :         const long long int ns_in_year = 31536000000000000LL;
      93                 :             : 
      94                 :             :         /// Number of nanoseconds in a month
      95                 :             :         /// ns_in_year/12
      96                 :         569 :         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                 :         569 :         const long long int ns_in_week = 604800000000000LL;
     101                 :             : 
     102                 :             :         /// Number of nanoseconds in a day
     103                 :             :         /// 24*60*60*1000*1000*1000
     104                 :         569 :         const long long int ns_in_day = 86400000000000LL;
     105                 :             : 
     106                 :             :         /// Number of nanoseconds in an hour
     107                 :             :         /// 60*60*1000*1000*1000
     108                 :         569 :         const long long int ns_in_hour = 3600000000000LL;
     109                 :             : 
     110                 :             :         /// Number of nanoseconds in a minute
     111                 :             :         /// 60*1000*1000*1000
     112                 :         569 :         const long long int ns_in_minute = 60000000000LL;
     113                 :             : 
     114                 :             :         /// Number of nanoseconds in a second
     115                 :             :         /// 1000*1000*1000
     116                 :         569 :         const long long int ns_in_second = 1000000000LL;
     117                 :             : 
     118                 :             :         /// Number of nanoseconds in a millisecond
     119                 :             :         /// 1000*1000
     120                 :         569 :         const long long int ns_in_millisecond = 1000000LL;
     121                 :             : 
     122                 :             :         /// Number of nanoseconds in a microsecond
     123                 :             :         /// 1000
     124                 :         569 :         const long long int ns_in_microsecond = 1000LL;
     125                 :             : 
     126                 :             :         // Initializing the structure that will be returned from the function
     127                 :         569 :         Date date = {0};
     128                 :             : 
     129                 :         569 :         date.years = nanoseconds/ns_in_year;
     130                 :             : 
     131                 :         569 :         const long long int years_ns = date.years * ns_in_year;
     132                 :         569 :         date.months = (nanoseconds - years_ns)/ns_in_month;
     133                 :             : 
     134                 :         569 :         const long long int months_ns = date.months * ns_in_month;
     135                 :         569 :         date.weeks = (nanoseconds - years_ns - months_ns)/ns_in_week;
     136                 :             : 
     137                 :         569 :         const long long int weeks_ns = date.weeks * ns_in_week;
     138                 :         569 :         date.days = (nanoseconds - years_ns - months_ns - weeks_ns)/ns_in_day;
     139                 :             : 
     140                 :         569 :         const long long int days_ns = date.days * ns_in_day;
     141                 :         569 :         date.hours = (nanoseconds - years_ns - months_ns - weeks_ns - days_ns)/ns_in_hour;
     142                 :             : 
     143                 :         569 :         const long long int hours_ns = date.hours * ns_in_hour;
     144                 :         569 :         date.minutes = (nanoseconds - years_ns - months_ns - weeks_ns - days_ns - hours_ns)/ns_in_minute;
     145                 :             : 
     146                 :         569 :         const long long int minutes_ns = date.minutes * ns_in_minute;
     147                 :         569 :         date.seconds = (nanoseconds - years_ns - months_ns - weeks_ns - days_ns - hours_ns - minutes_ns)/ns_in_second;
     148                 :             : 
     149                 :         569 :         const long long int seconds_ns = date.seconds * ns_in_second;
     150                 :         569 :         date.milliseconds = (nanoseconds - years_ns - months_ns - weeks_ns - days_ns - hours_ns - minutes_ns - seconds_ns)/ns_in_millisecond;
     151                 :             : 
     152                 :         569 :         const long long int milliseconds_ns = date.milliseconds * ns_in_millisecond;
     153                 :         569 :         date.microseconds = (nanoseconds - years_ns - months_ns - weeks_ns - days_ns - hours_ns - minutes_ns - seconds_ns - milliseconds_ns)/ns_in_microsecond;
     154                 :             : 
     155                 :         569 :         const long long int microseconds_ns = date.microseconds * ns_in_microsecond;
     156                 :         569 :         date.nanoseconds = (nanoseconds - years_ns - months_ns - weeks_ns - days_ns - hours_ns - minutes_ns - seconds_ns - milliseconds_ns - microseconds_ns);
     157                 :             : 
     158                 :         569 :         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                 :        3530 : 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   [ +  +  -  + ]:        3530 :         if(number <= 0LL || *used_len >= result_size)
     176                 :             :         {
     177                 :        2448 :                 return;
     178                 :             :         }
     179                 :             : 
     180         [ -  + ]:        1082 :         if(*used_len >= result_size)
     181                 :             :         {
     182                 :           0 :                 return;
     183                 :             :         }
     184                 :             : 
     185                 :        1082 :         const int written = snprintf(result + *used_len,result_size - *used_len,"%lld%s ",number,suffix);
     186                 :             : 
     187         [ -  + ]:        1082 :         if(written < 0)
     188                 :             :         {
     189                 :           0 :                 return;
     190                 :             :         }
     191                 :             : 
     192                 :        1082 :         const size_t write_size = (size_t)written;
     193                 :             : 
     194         [ +  + ]:        1082 :         if(write_size >= result_size - *used_len)
     195                 :             :         {
     196                 :           2 :                 *used_len = result_size - 1ULL;
     197                 :           2 :                 result[result_size - 1ULL] = '\0';
     198                 :             :         } else {
     199                 :        1080 :                 *used_len += write_size;
     200                 :             :         }
     201                 :             : }
     202                 :             : 
     203                 :             : /**
     204                 :             :  *
     205                 :             :  * Convert nanoseconds to human-readable date as a string
     206                 :             :  *
     207                 :             :  */
     208                 :         605 : char *form_date_r(
     209                 :             :         const long long int nanoseconds,
     210                 :             :         const ByteFormat    format,
     211                 :             :         char                *buffer,
     212                 :             :         const size_t        buffer_size)
     213                 :             : {
     214   [ +  +  +  + ]:         605 :         if(buffer == NULL || buffer_size == 0ULL)
     215                 :             :         {
     216                 :           2 :                 return(NULL);
     217                 :             :         }
     218                 :             : 
     219                 :         603 :         buffer[0] = '\0';  /* Initialize buffer as empty string */
     220                 :         603 :         size_t used_len = 0ULL;
     221                 :             : 
     222                 :             :         // If the time passed as argument is less than one nanosecond
     223         [ +  + ]:         603 :         if(nanoseconds == 0LL)
     224                 :             :         {
     225                 :          34 :                 (void)snprintf(buffer,buffer_size,"0ns");
     226                 :          34 :                 return(buffer);
     227                 :             :         }
     228                 :             : 
     229                 :             :         Date date = asadate(nanoseconds);
     230                 :             : 
     231         [ +  + ]:         569 :         if(format == MAJOR_VIEW)
     232                 :             :         {
     233         [ -  + ]:         240 :                 if(date.years > 0LL)
     234                 :             :                 {
     235                 :           0 :                         catdate_r(buffer,buffer_size,&used_len,date.years,"y");
     236         [ -  + ]:         240 :                 } else if(date.months > 0LL){
     237                 :           0 :                         catdate_r(buffer,buffer_size,&used_len,date.months,"mon");
     238         [ -  + ]:         240 :                 } else if(date.weeks > 0LL){
     239                 :           0 :                         catdate_r(buffer,buffer_size,&used_len,date.weeks,"w");
     240         [ -  + ]:         240 :                 } else if(date.days > 0LL){
     241                 :           0 :                         catdate_r(buffer,buffer_size,&used_len,date.days,"d");
     242         [ +  + ]:         240 :                 } else if(date.hours > 0LL){
     243                 :           1 :                         catdate_r(buffer,buffer_size,&used_len,date.hours,"h");
     244         [ -  + ]:         239 :                 } else if(date.minutes > 0LL){
     245                 :           0 :                         catdate_r(buffer,buffer_size,&used_len,date.minutes,"min");
     246         [ +  + ]:         239 :                 } else if(date.seconds > 0LL){
     247                 :           7 :                         catdate_r(buffer,buffer_size,&used_len,date.seconds,"s");
     248         [ +  + ]:         232 :                 } else if(date.milliseconds > 0LL){
     249                 :         191 :                         catdate_r(buffer,buffer_size,&used_len,date.milliseconds,"ms");
     250         [ +  + ]:          41 :                 } else if(date.microseconds > 0LL){
     251                 :          37 :                         catdate_r(buffer,buffer_size,&used_len,date.microseconds,"μs");
     252                 :             :                 } else {
     253                 :           4 :                         catdate_r(buffer,buffer_size,&used_len,date.nanoseconds,"ns");
     254                 :             :                 }
     255                 :             :         } else {
     256                 :         329 :                 catdate_r(buffer,buffer_size,&used_len,date.years,"y");
     257                 :         329 :                 catdate_r(buffer,buffer_size,&used_len,date.months,"mon");
     258                 :         329 :                 catdate_r(buffer,buffer_size,&used_len,date.weeks,"w");
     259                 :         329 :                 catdate_r(buffer,buffer_size,&used_len,date.days,"d");
     260                 :         329 :                 catdate_r(buffer,buffer_size,&used_len,date.hours,"h");
     261                 :         329 :                 catdate_r(buffer,buffer_size,&used_len,date.minutes,"min");
     262                 :         329 :                 catdate_r(buffer,buffer_size,&used_len,date.seconds,"s");
     263                 :         329 :                 catdate_r(buffer,buffer_size,&used_len,date.milliseconds,"ms");
     264                 :         329 :                 catdate_r(buffer,buffer_size,&used_len,date.microseconds,"μs");
     265                 :         329 :                 catdate_r(buffer,buffer_size,&used_len,date.nanoseconds,"ns");
     266                 :             :         }
     267                 :             : 
     268                 :             :         // Remove trailing space at the end of the line.
     269   [ +  +  +  - ]:         569 :         if(used_len > 0ULL && buffer[used_len - 1ULL] == ' ')
     270                 :             :         {
     271                 :         568 :                 buffer[used_len - 1ULL] = '\0';
     272                 :             :         }
     273                 :             : 
     274                 :         569 :         return(buffer);
     275                 :             : }
     276                 :             : 
     277                 :             : /**
     278                 :             :  *
     279                 :             :  * Convert nanoseconds to human-readable date as a string
     280                 :             :  *
     281                 :             :  */
     282                 :         244 : char *form_date(
     283                 :             :         const long long int nanoseconds,
     284                 :             :         const ByteFormat    format)
     285                 :             : {
     286                 :             :         // Zero out a static memory area with a string array
     287                 :             :         static char result[MAX_CHARACTERS];
     288                 :             : 
     289                 :         244 :         return(form_date_r(nanoseconds,format,result,sizeof(result)));
     290                 :             : }
     291                 :             : #if 0
     292                 :             : /// Test
     293                 :             : 
     294                 :             : /// To build
     295                 :             : /// gcc -I../../logger/lib/ time.c
     296                 :             : 
     297                 :             : /// 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
     298                 :             : /// Should be 10y 9mon 1w 2d 3h 4min 5s 368ms 118μs 513ns
     299                 :             : 
     300                 :             : int main(void)
     301                 :             : {
     302                 :             :         long long int ns = 339800645368118513LL;
     303                 :             :         printf("%s\n",form_date(ns,FULL_VIEW));
     304                 :             : 
     305                 :             :         printf("%s\n",form_date(273522528,FULL_VIEW));
     306                 :             : 
     307                 :             :         return 0;
     308                 :             : }
     309                 :             : #endif
        

Generated by: LCOV version 2.0-1