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
|