How can I get the current time in milliseconds using C? - c

How might I get the current time in milliseconds in C? I am doing following to get the time in seconds:
struct tm ptm;
now = time(NULL);
localtime_r(&now,ptm);
myTime= (ptm->tm_hour * 3600) + (ptm->tm_min * 60) + (ptm->tm_sec);
Looking at time.h, struct tm does not have the millisecond member in it.

On Unix, use gettimeofday() to get the answer in microseconds and scale to milliseconds.
Or use POSIX clock_gettime() to get the answer in nanoseconds and scale to milliseconds.

I use ftime for time tracking (link text)

Related

C find elapsed time in C Linux

I have to calculate the time taken by a function to complete.
This function is called in a loop and I want to find out the total time.
Usually the time is very less in either nano or micro seconds.
To find out the elapsed time I used functions gettimeofday() using struct timeval and clock_gettime() using struct timespec.
Problem is time return by timeval in seconds is correct but in micro seconds wrong.
Similarly the time returned by timespec in nano seconds is wrong.
Wrong in the sense they do not tally with the time returned in seconds.
For clock_gettime() I tried both CLOCK_PROCESS_CPUTIME_ID and CLOCK_MONOTONIC.
Using clock() also does not help.
Code snippet:
struct timeval funcTimestart_timeval, funcTimeEnd_timeval;
struct timespec funcTimeStart_timespec, funcTimeEnd_timespec;
unsigned long elapsed_nanos = 0;
unsigned long elapsed_seconds = 0;
unsigned long diffInNanos = 0;
unsigned long Func_elapsed_nanos = 0;
unsigned long Func_elapsed_seconds = 0;
while(...)
{
gettimeofday(&funcTimestart_timeval, NULL);
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &funcTimeStart_timespec);
...
demo_func();
...
gettimeofday(&funcTimeEnd_timeval, NULL);
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &funcTimeEnd_timespec);
elapsed_seconds = funcTimeEnd_timeval.tv_sec - funcTimestart_timeval.tv_sec;
Func_elapsed_seconds+= elapsed_seconds;
elapsed_nanos = funcTimeEnd_timespec.tv_nsec - funcTimeStart_timespec.tv_nsec;
Func_elapsed_nanos+ = elapsed_nanos;
}
printf("Total time taken by demo_func() is %lu seconds( %lu nanoseconds )\n", Func_elapsed_seconds, Func_elapsed_nanos );
Printf output:
Total time taken by demo_func() is 60 seconds( 76806787 nanoseconds )
See that the time in seconds and nanoseconds do not match.
How to resolve this issue or any other appropriate method to find elapsed time?
Did you read the documentation of time(7) and clock_gettime(2)? Please read it twice.
The struct timespec is not supposed to express twice the same time. The field tv_sec gives the second part ts, and the field tv_nsec gives the nanosecond part tn to express the time t = ts + 10-9 tn
I would suggest to convert that to a floating point, e.g.
printf ("total time %g\n",
(double)Func_elapsed_seconds + 1.0e-9*Func_elapsed_nanos);
Using floating point is simpler and generally the precision is enough for most needs. Otherwise, when you add or substract struct timespec you need to handle the case when the added/substracted tv_nsec field sum/difference is negative or more than 1000000000....
The problem is you are printing/comparing wrong values.
76,806,787 nanoseconds is equal to ~76 milliseconds, you cannot compare it with 60 seconds.
You are ignoring the time in seconds stored in funcTimeEnd_timespec.tv_sec.
You should also print funcTimeEnd_timespec.tv_sec - funcTimeStart_timespec.tv_sec, and as #Basile Starynkevitch suggested, add with it the nanoseconds part after multiplying it with 10e-9. Then you can compare time elapsed shown by both functions.
I am replying to the previous answers as answer as I wanted to paste code snippets.
Question is to find out elapsed time whether
first I should subtract the corresponding times with each other and then add
(end.tv_sec - start.tv_sec) + 1.0e-9*(end.tv_nsec - start.tv_nsec)
or
first add the times and then compute the difference
(end.tv_sec + 1.0e-9*end.tv_nsec) - (start.tv_sec + 1.0e-9*start.tv_nsec)
In the first case quite often end.tv_nsec is less in number then start.tv_nsec and hence the difference becomes negative number nd this give me wrong number.

Getting Duration

I'm trying to measure duration of something.
when it start I call start_time = time(NULL);
when it ends:
time_t a_time = time(NULL) - start_time;
struct tm * ts = localtime(&a_time);
char time_buff[32];
memset (time_buff,0,32);
sprintf (time_buff, "Duration: %02d:%02d:%02d", ts->tm_hour, ts->tm_min, ts->tm_sec);
The problem is that ts->tm_hour is always 2.
Please advise.
Thanks,
Nahum
The function localtime converts the time to a complete date and time. You better convert it to days, hours and minutes yourself though divisions and modulo operations.
do you eventualy live in a country where the time is 2 hours away from UTC time ?
replace your call to localtime() (which is in your current timezone) by a call to gmtime().
Why not use a function that returns the amount of milliseconds elapsed (clock or gettimeofday) and then convert to hour/min/sec?

C - gettimeofday for computing time?

do you know how to use gettimeofday for measuring computing time? I can measure one time by this code:
char buffer[30];
struct timeval tv;
time_t curtime;
gettimeofday(&tv, NULL);
curtime=tv.tv_sec;
strftime(buffer,30,"%m-%d-%Y %T.",localtime(&curtime));
printf("%s%ld\n",buffer,tv.tv_usec);
This one is made before computing, second one after. But do you know how to subtracts it?
I need result in miliseconds
To subtract timevals:
gettimeofday(&t0, 0);
/* ... */
gettimeofday(&t1, 0);
long elapsed = (t1.tv_sec-t0.tv_sec)*1000000 + t1.tv_usec-t0.tv_usec;
This is assuming you'll be working with intervals shorter than ~2000 seconds, at which point the arithmetic may overflow depending on the types used. If you need to work with longer intervals just change the last line to:
long long elapsed = (t1.tv_sec-t0.tv_sec)*1000000LL + t1.tv_usec-t0.tv_usec;
The answer offered by #Daniel Kamil Kozar is the correct answer - gettimeofday actually should not be used to measure the elapsed time. Use clock_gettime(CLOCK_MONOTONIC) instead.
Man Pages say - The time returned by gettimeofday() is affected by discontinuous jumps in the system time (e.g., if the system administrator manually changes the system time). If you need a monotonically increasing clock, see clock_gettime(2).
The Opengroup says - Applications should use the clock_gettime() function instead of the obsolescent gettimeofday() function.
Everyone seems to love gettimeofday until they run into a case where it does not work or is not there (VxWorks) ... clock_gettime is fantastically awesome and portable.
<<
If you want to measure code efficiency, or in any other way measure time intervals, the following will be easier:
#include <time.h>
int main()
{
clock_t start = clock();
//... do work here
clock_t end = clock();
double time_elapsed_in_seconds = (end - start)/(double)CLOCKS_PER_SEC;
return 0;
}
hth
No. gettimeofday should NEVER be used to measure time.
This is causing bugs all over the place. Please don't add more bugs.
Your curtime variable holds the number of seconds since the epoch. If you get one before and one after, the later one minus the earlier one is the elapsed time in seconds. You can subtract time_t values just fine.

How to get current hour (time of day) in linux kernel space

I'm writing a kernel module that checks to see if the time is between two specified hours, and disables input if it is. This has to do with me wanting to make sure I go to bed early. (I know I could also use any number of different techniques including cron etc, but I wanted to learn kernel programming...)
As a first version, I therefore check if the current hour is between start and end, which are set via parameters to the module.
My question is therefore : How do I get the current hour? I have no access to the usual time functions in the standard library because I am in kernel space. I'm guessing that I should be using do_gettimeofday() for this, but that only gives me seconds and nanoseconds, and I need hours in the current day.
Thanks.
time_to_tm function can be of your help, which returns the structure tm. Timezone available in variable sys_tz, it can help you to set your offset properly to get local time.
To get the local time in kernel, add the below code snippet your kernel driver:
struct timeval time;
unsigned long local_time;
do_gettimeofday(&time);
local_time = (u32)(time.tv_sec - (sys_tz.tz_minuteswest * 60));
rtc_time_to_tm(local_time, &tm);
printk(" # (%04d-%02d-%02d %02d:%02d:%02d)\n", tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec);
This works well for me:
#include <linux/time.h>
...
/* getnstimeofday - Returns the time of day in a timespec */
void getnstimeofday(struct timespec *ts)
For getting usual time format you can use:
printk("TIME: %.2lu:%.2lu:%.2lu:%.6lu \r\n",
(curr_tm.tv_sec / 3600) % (24),
(curr_tm.tv_sec / 60) % (60),
curr_tm.tv_sec % 60,
curr_tm.tv_nsec / 1000);
Converting the do_gettimeofday result to an hour is pretty simple, since it starts at midnight GMT.
time_t t = time(0);
time_t SecondsOfDay = t % (24*60*60);
time_t HourGMT = SecondsOfDay / (60*60);
Then adjust for your local timezone
We can use clock_gettime function with CLOCK_REALTIME as the type of clock.
Reference http://linux.die.net/man/3/clock_gettime
Just doing a strace on date executable gives us an idea to get the current date in the kernel mode.

Regarding getting time in milliseconds

I am working on logger using C language on QNX platform using Momnetics to print time in following format
2010-11-02 14:45:15.000
I able to get date, hour, minutes, and seconds using
time(&timeSpec);
struct tm gmt;
int iSysTimeSec = timeSpec;
gmtime_r((time_t *)&iSysTimeSec, &gmt);
sprintf(&MsgStamp[0], SYS_MSG_STAMP_PRINTF_FORMAT, gmt.tm_year+1900, gmt.tm_mon + 1, gmt.tm_mday, gmt.tm_hour, gmt.tm_min, gmt.tm_sec, iSysTimeMs );
Question is how do i get milliseconds granularity using QNX Momentics.
I tried to get granulaity for milliseconds using QNX specific
int iSysTimeMs = ( (ClockCycles () * 1000) / SYSPAGE_ENTRY(qtime)->cycles_per_sec ) % 1000;
but i want to do this POSIX way so that it is portable. How do we do this?
Thanks!
Venkata
In QNX6 You can use the clock_gettime to have the max granularity
allowed by system.
struct timespec start;
clock_gettime( CLOCK_REALTIME, &start);
The gettimeofday() system call will return a structure holding the current Unix time in seconds and the number of microseconds belonging to the current second.
To get the total number of microseconds:
struct timeval tv;
gettimeofday(&tv, NULL);
u_int64_t now = tv.tv_sec * 1000000ULL + tv.tv_usec;

Resources