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
|