Retrieve Linux Time using struct timespec
Solution 1
After calling clock_gettime
, ts.tv_sec
, which has type time_t
, is populated with the timestamp in seconds since the epoch. You can pass that directly to localtime
:
struct timespec ts;
clock_gettime(clk_id, &ts);
struct tm *my_tm = localtime(&ts.tv_sec);
Now my_tm
points to a struct tm
which has the time broken down into year / month / day / hour / minute / second, and ts.tv_nsec
has the nanosecond portion.
Solution 2
What keeps you from doing:
#include <time.h>
#include <stdio.h>
#include <string.h>
int main(void)
{
struct timespec ts;
clock_gettime(CLOCK_REALTIME, &ts);
char * p = ctime(&ts.tv_sec); /* Note that ctime() isn't thread-safe. */
p[strcspn(p, "\r\n")] = 0;
printf("Date: %s %ldns\n", p, ts.tv_nsec);
...
}
From the relevant documentation:
All implementations support the system-wide real-time clock, which is identified by CLOCK_REALTIME. Its time represents seconds and nanoseconds since the Epoch.
(POSIX documentation is here.)
Related videos on Youtube
Irfan
Updated on June 04, 2022Comments
-
Irfan almost 2 years
Can someone please suggest how can I retrieve linux time using
struct timespec ts
type? It just gives me time since Epoch. Can I get the actual Linux time using this datatype?
Brief Background: I am writing a logger utility on embedded device with timestamp resolution in milli/micro seconds. The source adds timestamp which is consumed by destination component.
struct stLogItem logitem; //stLogItem has a member, struct timespec ts clock_gettime(clk_id, &logitem.ts);
The destination component is printing this log timestamp on file/console. But the date which is printed out is time since Epoch, and not the actual Linux date.
The printed data is: 1970-01-01 23:30:07.586864475
Whereas, the Linux date is different as shown below:
root@imh:# date
Tue Nov 14 11:34:12 UTC 2017
Its not a format issue. It is about getting the current Linux time (in nano seconds).
-
unwind over 6 yearsWhat is "actual Linux time"? Time since the first announcement by Linus? :)
-
alk over 6 yearsYou might like to have a look at
localtime*()
. -
Irfan over 6 yearsTue Nov 14 10:06:34 UTC 2017 (after typing "date" on shell)
-
Ronny Brendel over 6 yearsGoogle how to get date and time in linux c. time(), localtime()
-
Irfan over 6 yearsI am using struct timespec for best resolution.
-
Irfan over 6 yearsdoes it suggest that I can not retrieve Linux time through "struct timespec"?
-
tripleee over 6 yearsReturning time as a simple scalar is a feature, not a bug. You have to convert it to a human-readable format separately if that's what you want.
-
tripleee over 6 yearsPossible duplicate of How do I make a human-readable string out of a struct tm?
-
danglingpointer over 6 yearsDo you want to get the elapsed real time using the
clock_gettime
call? -
Irfan over 6 yearsIts not a conversion problem. Its about getting current time. I am already printing human readable time on console. The output shows it: " 1970-01-01 22:17:01.776871940"
-
Irfan over 6 yearsusing timespec, I want to retrieve the same date and time as returned by localtime(...) function.
-
alk over 6 yearsWhat is
clk_id
and how is it set? -
dbush over 6 yearsThis update isn't enough. You need to show the actual code that produces the invalid output.
-
Irfan over 6 years@dbush, directly after retrieving the ts value by line, "clock_gettime(clk_id, &logitem.ts);", I have used the solution which you have provided and the solution alk has provided. Both of these solutions produce the output I mentioned.
-
Irfan over 6 yearsPlease refer to my first comment on alk's post. Which shows output using his solution.
-
dbush over 6 yearsWhen I run his code I get "Date: Tue Nov 28 09:41:03 2017 378233094ns" as output. If running "date" from the shell gives you the proper time, you're doing sometime different. Show your code.
-
Irfan over 6 years@alk, the clk_id is CLOCK_REALTIME. Infact, I pass it as it is. Means clk_id was just placeholder for actual value.
-
alk over 6 yearsDid you take my code as is and compiled it as is, no additions, no removals (despite the
...
) to a single main?
-
-
Irfan over 6 yearsthis just prints the output "Thu Jan 1 23:28:20 1970 690758173ns " where as the result of "date" command gives output "Tue Nov 14 10:59:57 UTC 2017". You can see two dates have different time values (just forget about format)
-
Irfan over 6 yearsAnd this is due to the fact that ts variable has that time. ctime just returns the input time as string
-
alk over 6 years@Irfan: If the above code really gives you "Thu Jan 1 23:28:20 1970 ..." it seems your system clock is messed up, running on the wrong time.
-
dbush over 6 years@Irfan You should update your question with the actual code that produces that output. It's likely you're doing something else wrong.
-
Jonathan Leffler over 6 yearsNote that the
tm_year
andtm_mon
fields of the broken down time have oddball encodings, andstrftime()
can be used to format time strings (but nanoseconds have to be handled separately and carefully). -
Gabriel Staples about 2 yearsHere is the documentation on
localtime()
andlocaltime_r()
: man7.org/linux/man-pages/man3/localtime.3p.html. Note thatlocaltime()
is not thread-safe. If you need a threadsafe version, use thelocaltime_r()
"re-entrant" (thread-safe) version. -
Gabriel Staples about 2 yearsThank you! I used your example to write my own. I needed the help to see how to use
localtime()
. I've expanded your answer a lot and added a bunch more output, such as formatting the output asFri Apr 15 14:05:12 2022 -0700
, in my own answer here.