Getting the localtime in milliseconds - c

I need the fastest way to get the localtime (thus considering the current timezone) at least in milliseconds precision, if is possible to get in tenths of milliseconds it would be better.
I would like to avoid the use of gettimeofday() as it is now an obsolete function.
So, there seems that I'll need to use the clock_gettime(CLOCK_REALTIME, ...) and adjust the hour to the current timezone, but how ? And where is the best point to do that ? Before to store the timestamp got with clock_gettime, or before to convert it in a gregorian calendar in the current timezone?
EDIT: My original sample joining get_clock and localtime - There are better ways to reach that?
#include <time.h>
#include <stdio.h>
int main() {
struct timespec ts;
clock_gettime(CLOCK_REALTIME, &ts);
struct tm* ptm;
ptm = localtime(&(ts.tv_sec));
// Tenths of milliseconds (4 decimal digits)
int tenths_ms = ts.tv_nsec / (100000L);
printf("%04d-%02d-%02d %02d:%02d:%02d.%04d\n",
1900 + ptm->tm_year, ptm->tm_mon + 1, ptm->tm_mday,
ptm->tm_hour, ptm->tm_min, ptm->tm_sec, tenths_ms);
}

I don't think there's a better way than with clock_gettime() and localtime(). However you need to round the returned nanoseconds correctly and consider the case when the time is rounded up to the next second. To format the time you can use strftime() instead of formatting the tm struct manually:
#include <time.h>
#include <stdio.h>
int main(void) {
struct timespec ts;
long msec;
int err = clock_gettime(CLOCK_REALTIME, &ts);
if (err) {
perror("clock_gettime");
return 1;
}
// round nanoseconds to milliseconds
if (ts.tv_nsec >= 999500000) {
ts.tv_sec++;
msec = 0;
} else {
msec = (ts.tv_nsec + 500000) / 1000000;
}
struct tm* ptm = localtime(&ts.tv_sec);
if (ptm == NULL) {
perror("localtime");
return 1;
}
char time_str[sizeof("1900-01-01 23:59:59")];
time_str[strftime(time_str, sizeof(time_str),
"%Y-%m-%d %H:%M:%S", ptm)] = '\0';
printf("%s.%03li\n", time_str, msec);
}

Yes, this can be achieved using the clock_gettime() function. In the current version of POSIX, gettimeofday() is marked obsolete. This means it may be removed from a future version of the specification. Application writers are encouraged to use the clock_gettime() function instead of gettimeofday().
Long story short, here is an example of how to use clock_gettime():
#define _POSIX_C_SOURCE 200809L
#include <inttypes.h>
#include <math.h>
#include <stdio.h>
#include <time.h>
void print_current_time_in_ms (void)
{
long ms; // Milliseconds
time_t s; // Seconds
struct timespec spec;
clock_gettime(CLOCK_REALTIME, &spec);
s = spec.tv_sec;
ms = round(spec.tv_nsec / 1.0e6); // Convert nanoseconds to milliseconds
printf("Current time: %"PRIdMAX".%03ld seconds since the Epoch\n",
(intmax_t)s, ms);
}
If your goal is to measure elapsed time, and your system supports the "monotonic clock" option, then you should consider using CLOCK_MONOTONIC instead of CLOCK_REALTIME.
One more point, remember to include -lm flag when trying to compile the code.
To get the timezone, just do the following:
#define _GNU_SOURCE /* for tm_gmtoff and tm_zone */
#include <stdio.h>
#include <time.h>
int main(void)
{
time_t t = time(NULL);
struct tm lt = {0};
localtime_r(&t, &lt);
printf("Offset to GMT is %lds.\n", lt.tm_gmtoff);
printf("The time zone is '%s'.\n", lt.tm_zone);
return 0;
}
Note: The seconds since epoch returned by time() are measured as if in GMT (Greenwich Mean Time).

Related

Dates difference in C (seconds)

I have never programmed in C and therefore it is being a real challenge to write a small piece of software which returns the difference between two dates in seconds.
Just as background information, I implemented a kind of heart beat in a Python application with updates a txt file every 15 seconds. Now I would like to create a C application that checks this txt constantly and in case the difference is greater than 30 seconds, it restarts my computer.
That is how far I went so far:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <sys/stat.h>
#include <sys/types.h>
//Returns the number seconds since the last time the files has been updated
int lastUpdate() {
struct stat attr;
stat("watcher.txt", &attr);
//Gets the last update in the following format: Mon Aug 13 08:23:14 2012
//ctime(&attr.st_mtime);
time_t lastChange = &attr.st_mtime
time_t now = time(0)
//No idea how to implement it :-(
//int seconds = timediff(now, lastChange)
return seconds;
}
//Constantly checks if application is sending heart beats in a 30 seconds time frame
main()
{
while(1 == 1)
{
if(lastUpdate() > 30)
{
sprintf(cmd, "sudo reboot -i -p");
system(cmd);
}
}
}
Would anyone be so nice and give some hints on how to get this working?
Thank you very much!
EDITED:
Final code working without issues:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <sys/stat.h>
#include <sys/types.h>
//Returns the number seconds since the last time the files has been updated
int lastUpdate() {
struct stat attr;
stat("/home/pi/watcher.txt", &attr);
time_t lastChange = attr.st_mtime;
time_t now = time(0);
int seconds = now - lastChange;
return seconds;
}
//Constantly checks if application is sending heart beats in a 30 seconds time frame
main()
{
sleep(120);
while(1 == 1)
{
sleep(1);
if(lastUpdate() > 30)
{
system("sudo reboot -i -p");
}
}
}
You're in luck! time_t is a number, and the timestamps are the time since the beginning of 1970 in seconds. So:
int seconds = now - lastChange;
Oh, and
time_t lastChange = &attr.st_mtime
should be
time_t lastChange = attr.st_mtime
time_t is typically the number of seconds since Jan 1, 1970 0:00:00 UTC (GMT ). So a simply subtraction will work.
time_t lastChange = &attr.st_mtime
time_t now = time(0)
time_t seconds = now - lastChange;
printf("%ll\n", (long long) seconds);
Stricly speaking, time_t may be some other scalar.
A portable solution is to use double difftime(time_t time1, time_t time0);
#include <time.h>
double seconds = difftime(now, lastChange);
printf("%f\n", seconds);
You just need to subtract the time_t's but you have a problem in this line
time_t lastChange = &attr.st_mtime
because stat.st_mtime is of type time_t not time_t *, so you should change it to
time_t lastChange = attr.st_mtime
and then
return new - lastChange;
and also, check stat("watcher.txt", &attr) != -1

How to print time difference in accuracy of milliseconds and nanoseconds from C in Linux?

I have this program which prints the time difference between 2 different instances, but it prints in accuracy of seconds. I want to print it in milliseconds and another in nanoseconds difference.
//Prints in accuracy of seconds
#include <stdio.h>
#include <time.h>
int main(void)
{
time_t now, later;
double seconds;
time(&now);
sleep(2);
time(&later);
seconds = difftime(later, now);
printf("%.f seconds difference", seconds);
}
How can I accomplish that?
Read first the time(7) man page.
Then, you can use clock_gettime(2) syscall (you may need to link -lrt to get it).
So you could try
struct timespec tstart={0,0}, tend={0,0};
clock_gettime(CLOCK_MONOTONIC, &tstart);
some_long_computation();
clock_gettime(CLOCK_MONOTONIC, &tend);
printf("some_long_computation took about %.5f seconds\n",
((double)tend.tv_sec + 1.0e-9*tend.tv_nsec) -
((double)tstart.tv_sec + 1.0e-9*tstart.tv_nsec));
Don't expect the hardware timers to have a nanosecond accuracy, even if they give a nanosecond resolution. And don't try to measure time durations less than several milliseconds: the hardware is not faithful enough. You may also want to use clock_getres to query the resolution of some clock.
timespec_get from C11
This function returns up to nanoseconds, rounded to the resolution of the implementation.
Example from: http://en.cppreference.com/w/c/chrono/timespec_get :
#include <stdio.h>
#include <time.h>
int main(void)
{
struct timespec ts;
timespec_get(&ts, TIME_UTC);
char buff[100];
strftime(buff, sizeof buff, "%D %T", gmtime(&ts.tv_sec));
printf("Current time: %s.%09ld UTC\n", buff, ts.tv_nsec);
}
Output:
Current time: 02/18/15 14:34:03.048508855 UTC
More details here: https://stackoverflow.com/a/36095407/895245
here is a simple macro to deal with it
#include <time.h>
#define CHECK_TIME(x) {\
struct timespec start,end;\
clock_gettime(CLOCK_REALTIME, &start);\
x;\
clock_gettime(CLOCK_REALTIME, &end);\
double f = ((double)end.tv_sec*1e9 + end.tv_nsec) - ((double)start.tv_sec*1e9 + start.tv_nsec); \
printf("time %f ms\n",f/1000000); \
}
and here is how to use it:
CHECK_TIME(foo(a,b,c))

How to get the current time in milliseconds from C in Linux?

How do I get the current time on Linux in milliseconds?
This can be achieved using the POSIX clock_gettime function.
In the current version of POSIX, gettimeofday is marked obsolete. This means it may be removed from a future version of the specification. Application writers are encouraged to use the clock_gettime function instead of gettimeofday.
Here is an example of how to use clock_gettime:
#define _POSIX_C_SOURCE 200809L
#include <inttypes.h>
#include <math.h>
#include <stdio.h>
#include <time.h>
void print_current_time_with_ms (void)
{
long ms; // Milliseconds
time_t s; // Seconds
struct timespec spec;
clock_gettime(CLOCK_REALTIME, &spec);
s = spec.tv_sec;
ms = round(spec.tv_nsec / 1.0e6); // Convert nanoseconds to milliseconds
if (ms > 999) {
s++;
ms = 0;
}
printf("Current time: %"PRIdMAX".%03ld seconds since the Epoch\n",
(intmax_t)s, ms);
}
If your goal is to measure elapsed time, and your system supports the "monotonic clock" option, then you should consider using CLOCK_MONOTONIC instead of CLOCK_REALTIME.
You have to do something like this:
struct timeval tv;
gettimeofday(&tv, NULL);
double time_in_mill =
(tv.tv_sec) * 1000 + (tv.tv_usec) / 1000 ; // convert tv_sec & tv_usec to millisecond
Following is the util function to get current timestamp in milliseconds:
#include <sys/time.h>
long long current_timestamp() {
struct timeval te;
gettimeofday(&te, NULL); // get current time
long long milliseconds = te.tv_sec*1000LL + te.tv_usec/1000; // calculate milliseconds
// printf("milliseconds: %lld\n", milliseconds);
return milliseconds;
}
About timezone:
gettimeofday() support to specify timezone,
I use NULL, which ignore the timezone, but you can specify a timezone, if need.
#Update - timezone
Since the long representation of time is not relevant to or effected by timezone itself, so setting tz param of gettimeofday() is not necessary, since it won't make any difference.
And, according to man page of gettimeofday(), the use of the timezone structure is obsolete, thus the tz argument should normally be specified as NULL, for details please check the man page.
Use gettimeofday() to get the time in seconds and microseconds. Combining and rounding to milliseconds is left as an exercise.
C11 timespec_get
It returns up to nanoseconds, rounded to the resolution of the implementation.
It is already implemented in Ubuntu 15.10. API looks the same as the POSIX clock_gettime.
#include <time.h>
struct timespec ts;
timespec_get(&ts, TIME_UTC);
struct timespec {
time_t tv_sec; /* seconds */
long tv_nsec; /* nanoseconds */
};
More details here: https://stackoverflow.com/a/36095407/895245
This version need not math library and checked the return value of clock_gettime().
#include <time.h>
#include <stdlib.h>
#include <stdint.h>
/**
* #return milliseconds
*/
uint64_t get_now_time() {
struct timespec spec;
if (clock_gettime(1, &spec) == -1) { /* 1 is CLOCK_MONOTONIC */
abort();
}
return spec.tv_sec * 1000 + spec.tv_nsec / 1e6;
}
Derived from Dan Moulding's POSIX answer, this should work :
#include <time.h>
#include <math.h>
long millis(){
struct timespec _t;
clock_gettime(CLOCK_REALTIME, &_t);
return _t.tv_sec*1000 + lround(_t.tv_nsec/1e6);
}
Also as pointed out by David Guyon: compile with -lm
Jirka Justra's answer returns a long, which is usually 32 bits. The number of milliseconds since unix time 0 in 1970 requires more bits, so the data type
should be long long or unsigned long long, which is usually 64 bits. Also, as Kevin Thibedeau commented, rounding can be done without converting to floating point or using math.h.
#include <time.h>
long long millis () {
struct timespec t ;
clock_gettime ( CLOCK_REALTIME , & t ) ;
return t.tv_sec * 1000 + ( t.tv_nsec + 500000 ) / 1000000 ;
}
If you are trying to measure time less than 50 days, 32 bits is enough. Data type int is 32 bits or 64 bits on most computers, so the data type can be unsigned int.

How do I measure time in C?

I want to find out for how long (approximately) some block of code executes. Something like this:
startStopwatch();
// do some calculations
stopStopwatch();
printf("%lf", timeMesuredInSeconds);
How?
You can use the clock method in time.h
Example:
clock_t start = clock();
/*Do something*/
clock_t end = clock();
float seconds = (float)(end - start) / CLOCKS_PER_SEC;
You can use the time.h library, specifically the time and difftime functions:
/* difftime example */
#include <stdio.h>
#include <time.h>
int main ()
{
time_t start,end;
double dif;
time (&start);
// Do some calculation.
time (&end);
dif = difftime (end,start);
printf ("Your calculations took %.2lf seconds to run.\n", dif );
return 0;
}
(Example adapted from the difftime webpage linked above.)
Please note that this method can only give seconds worth of accuracy - time_t records the seconds since the UNIX epoch (Jan 1st, 1970).
Sometime it's needed to measure astronomical time rather than CPU time (especially this applicable on Linux):
#include <time.h>
double what_time_is_it()
{
struct timespec now;
clock_gettime(CLOCK_REALTIME, &now);
return now.tv_sec + now.tv_nsec*1e-9;
}
int main() {
double time = what_time_is_it();
printf("time taken %.6lf\n", what_time_is_it() - time);
return 0;
}
The standard C library provides the time function and it is useful if you only need to compare seconds. If you need millisecond precision, though, the most portable way is to call timespec_get. It can tell time up to nanosecond precision, if the system supports. Calling it, however, takes a bit more effort because it involves a struct. Here's a function that just converts the struct to a simple 64-bit integer.
#include <stdio.h>
#include <inttypes.h>
#include <time.h>
int64_t millis()
{
struct timespec now;
timespec_get(&now, TIME_UTC);
return ((int64_t) now.tv_sec) * 1000 + ((int64_t) now.tv_nsec) / 1000000;
}
int main(void)
{
printf("Unix timestamp with millisecond precision: %" PRId64 "\n", millis());
}
Unlike clock, this function returns a Unix timestamp so it will correctly account for the time spent in blocking functions, such as sleep. This is a useful property for benchmarking and implementing delays that take running time into account.
GetTickCount().
#include <windows.h>
void MeasureIt()
{
DWORD dwStartTime = GetTickCount();
DWORD dwElapsed;
DoSomethingThatYouWantToTime();
dwElapsed = GetTickCount() - dwStartTime;
printf("It took %d.%3d seconds to complete\n", dwElapsed/1000, dwElapsed - dwElapsed/1000);
}
I would use the QueryPerformanceCounter and QueryPerformanceFrequency functions of the Windows API. Call the former before and after the block and subtract (current − old) to get the number of "ticks" between the instances. Divide this by the value obtained by the latter function to get the duration in seconds.
For sake of completeness, there is more precise clock counter than GetTickCount() or clock() which gives you only 32-bit result that can overflow relatively quickly. It's QueryPerformanceCounter(). QueryPerformanceFrequency() gets clock frequency which is a divisor for two counters difference. Something like CLOCKS_PER_SEC in <time.h>.
#include <stdio.h>
#include <windows.h>
int main()
{
LARGE_INTEGER tu_freq, tu_start, tu_end;
__int64 t_ns;
QueryPerformanceFrequency(&tu_freq);
QueryPerformanceCounter(&tu_start);
/* do your stuff */
QueryPerformanceCounter(&tu_end);
t_ns = 1000000000ULL * (tu_end.QuadPart - tu_start.QuadPart) / tu_freq.QuadPart;
printf("dt = %g[s]; (%llu)[ns]\n", t_ns/(double)1e+9, t_ns);
return 0;
}
If you don't need fantastic resolution, you could use GetTickCount(): http://msdn.microsoft.com/en-us/library/ms724408(VS.85).aspx
(If it's for something other than your own simple diagnostics, then note that this number can wrap around, so you'll need to handle that with a little arithmetic).
QueryPerformanceCounter is another reasonable option. (It's also described on MSDN)

Calculating elapsed time in a C program in milliseconds

I want to calculate the time in milliseconds taken by the execution of some part of my program. I've been looking online, but there's not much info on this topic. Any of you know how to do this?
Best way to answer is with an example:
#include <sys/time.h>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
/* Return 1 if the difference is negative, otherwise 0. */
int timeval_subtract(struct timeval *result, struct timeval *t2, struct timeval *t1)
{
long int diff = (t2->tv_usec + 1000000 * t2->tv_sec) - (t1->tv_usec + 1000000 * t1->tv_sec);
result->tv_sec = diff / 1000000;
result->tv_usec = diff % 1000000;
return (diff<0);
}
void timeval_print(struct timeval *tv)
{
char buffer[30];
time_t curtime;
printf("%ld.%06ld", tv->tv_sec, tv->tv_usec);
curtime = tv->tv_sec;
strftime(buffer, 30, "%m-%d-%Y %T", localtime(&curtime));
printf(" = %s.%06ld\n", buffer, tv->tv_usec);
}
int main()
{
struct timeval tvBegin, tvEnd, tvDiff;
// begin
gettimeofday(&tvBegin, NULL);
timeval_print(&tvBegin);
// lengthy operation
int i,j;
for(i=0;i<999999L;++i) {
j=sqrt(i);
}
//end
gettimeofday(&tvEnd, NULL);
timeval_print(&tvEnd);
// diff
timeval_subtract(&tvDiff, &tvEnd, &tvBegin);
printf("%ld.%06ld\n", tvDiff.tv_sec, tvDiff.tv_usec);
return 0;
}
Another option ( at least on some UNIX ) is clock_gettime and related functions. These allow access to various realtime clocks and you can select one of the higher resolution ones and throw away the resolution you don't need.
The gettimeofday function returns the time with microsecond precision (if the platform can support that, of course):
The gettimeofday() function shall
obtain the current time, expressed as
seconds and microseconds since the
Epoch, and store it in the timeval
structure pointed to by tp. The
resolution of the system clock is
unspecified.
C libraries have a function to let you get the system time. You can calculate elapsed time after you capture the start and stop times.
The function is called gettimeofday() and you can look at the man page to find out what to include and how to use it.
On Windows, you can just do this:
DWORD dwTickCount = GetTickCount();
// Perform some things.
printf("Code took: %dms\n", GetTickCount() - dwTickCount);
Not the most general/elegant solution, but nice and quick when you need it.

Resources