Wall time with milliseconds in Linux C

104 Views Asked by At

Having found many quite old questions about this subject, I wonder if getting the current time in Linux C with year, month, day, hours, minutes, seconds and milliseconds still is so cumbersome these days.

I searched a lot but there are either structs holding the wall time without milliseconds, or structs returning the current time in milliseconds that I have to convert into wall time separately, or functions that return seconds and milliseconds in extra fields which would be ok to use but isn't what I'd call elegant.

Does a time struct like this

struct TIME_WITH_ALL_FIELDS now;
get_now(&now);
print ("today is ...",
  now.year, now.month, now.day,
  now.hour, now.minute, now.second, now.millisecond);

really not exist yet?

2

There are 2 best solutions below

1
12431234123412341234123 On BEST ANSWER

This is the way you get the time on Linux:

#include <time.h>
#include <stdio.h>
#include <string.h>

int main(void)
{
  struct timespec ts;    
  if(clock_gettime(CLOCK_REALTIME, &ts)<0)
    { perror("Can not get time"); return 1; }

  struct tm l;
  if(!gmtime_r(&ts.tv_sec,&l))
    { perror("Can not convert time"); return 1; }

  printf
    (
      "Timestamp (UTC): %04i-%02i-%02iT%02i:%02i:%02i.%03li \n", 
      l.tm_year+1900, l.tm_mon+1, l.tm_mday, l.tm_hour, l.tm_min, l.tm_sec, ts.tv_nsec/1000000
    );
}

If you think this isn't good enough for you, then you shouldn't use C.

It should be obvious why the syscall does only return time in second and nanosecond, and don't tell you anything about the day, year and month. This is why you have to convert it after you get the time from the kernel.

0
Bernd Benner On

You can get elapsed nano second from 1.1.1970 ( utc ) and so also milliseconds. Its possible to calculate date and time from the returned 64 bit value, but you have to handle time zone and daylight saving. ( calculate a offset )

include <time.h>

unsigned long long Getns()
{
  struct timespec ts;
  clock_gettime(CLOCK_REALTIME,&ts);
  //clock_gettime(CLOCK_MONOTONIC, &ts);
  return (ts.tv_sec * 1000000000) + ts.tv_nsec; 
}