1

The thing is, I have to somehow get current time of day in milliseconds in convenient format.

Example of desired output:

21 h 04 min 12 s 512 ms

I know how to get this format in seconds, but I have no idea how to get my hands on milliseconds?

Felix Glas
  • 15,065
  • 7
  • 53
  • 82
  • 2
    possible duplicate of http://stackoverflow.com/questions/19555121/how-to-get-current-timestamp-in-milliseconds-since-1970-just-the-way-java-gets – Pradheep Sep 30 '15 at 19:00
  • It's not a duplicate, @Pradheep but it is very similar. It'll probably require a more involved answer than what that question required. – Xirema Sep 30 '15 at 19:03
  • If Boost is supported on your platform, it is probably the only system-independent method. Otherwise, please specify an operating system and execution platform: Linux, MSDOS, MSWindows, OS/2, Unix, etc., 32-bit, 64-bit, JRE, etc. – wallyk Sep 30 '15 at 19:07

3 Answers3

10

Using the portable std::chrono

auto now = std::chrono::system_clock::now();
auto time = std::chrono::system_clock::to_time_t(now);
auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(now.time_since_epoch()) -
          std::chrono::duration_cast<std::chrono::seconds>(now.time_since_epoch());

std::cout << std::put_time(std::localtime(&time), "%H h %M m %S s ");
std::cout << ms.count() << " ms" << std::endl;

Output:

21 h 24 m 22 s 428 ms

Live example


Note for systems with clocks that doesn't support millisecond resolution

As pointed out by @user4581301, on some systems std::system_clock might not have enough resolution for accurately representing current time in milliseconds. If that is the case, try using std::high_resolution_clock for calculating the number of milliseconds since the last second. This will ensure the highest available resolution provided by your implementation.

Taking the time from two clocks will inevitably lead you to get two separate points in time (however small the time difference will be). So keep in mind that using a separate clock for calculating the milliseconds will not yield perfect synchronization between the second, and millisecond periods.

// Use system clock for time.
auto now = std::chrono::system_clock::now();

/* A small amount of time passes between storing the time points. */

// Use separate high resolution clock for calculating milliseconds.
auto hnow = std::chrono::high_resolution_clock::now();
auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(hnow.time_since_epoch()) -
          std::chrono::duration_cast<std::chrono::seconds>(hnow.time_since_epoch());

Also, there seems to be no guarantee that the tick events of std::high_resolution_clock and std::system_clock are synchronized, and because of this the millisecond period might not be in sync with the periodic update of the current second given by the system clock.

Because of these reasons, using a separate high resolution clock for millisecond resolution should not be used when <1 second precision is critical.

Community
  • 1
  • 1
Felix Glas
  • 15,065
  • 7
  • 53
  • 82
  • 1
    Thank Crom! I was looking at the other answers and wondering where the heck is std::chrono? The only problem here is on some systems you may have to switch to the high_resolution_clock to get the ms. system_clock should be good enough for modern desktop use, but test it to make sure the milliseconds are changing in ms, not 10s or 16s of ms. – user4581301 Sep 30 '15 at 19:34
  • @user4581301 Ah yes, thanks for pointing it out! Use [`std::high_resolution_clock`](http://en.cppreference.com/w/cpp/chrono/high_resolution_clock) when necessary. – Felix Glas Sep 30 '15 at 19:40
  • 1
    I'm going to disagree with using 'high_resolution_clock'. Newer versions of C++ removed 'to_time_t' from the high resolution clock, because it's not guaranteed to be aligned to any specific Epoch. In fact, most versions of the high resolution clock simply return the number of nanoseconds since the computer was turned on. Only 'system_clock' expressly provides a 'to_time_t' conversion in newer versions of C++. If you expressly need Millisecond precision in this kind of application, you should probably be tracking milliseconds a different way. – Xirema Sep 30 '15 at 19:59
  • @Xirema Ok, but then you can still use `std::high_resolution_clock` for calculating the number of milliseconds since the last second. The current local time have to be produced using `std::system_clock`. – Felix Glas Sep 30 '15 at 20:01
  • @Xirema just cut my comment off at the knees. It's not quite that simple. high_resolution_clock is the system's fastest clock and makes no pretenses of being mapped to a useful epoch without having a time_point of the time required, a time_point of the required epoch (*if this is possible* with the high_resolution_clock's implementation), and calculating the span between the two. Don't expect portability. – user4581301 Sep 30 '15 at 20:07
  • 1
    Yeah, but remember that that quantity of milliseconds is going to be aligned relative to when the computer is turned on, not to the System Clock's perception of each second relative to the Unix Time Stamp. 'high_resolution_clock' will report milliseconds of, say, 436 when the CPU is actually 243 milliseconds out from the second. Then when the hrc reports 798, the CPU would be 605 milliseconds out. Basically, if Millisecond resolution is important, It has to be measured relative to HRC, not to the System Clock. And you won't get "x milliseconds of the day" in "perfect", <1ms resolution. – Xirema Sep 30 '15 at 20:10
  • @Xirema Hmm, good point. It seems logical that there won't be any requirement for synchronization between the two different clocks. It appears to be a tricky cat to skin when the system clock doesn't have millisecond resolution. – Felix Glas Sep 30 '15 at 20:15
  • @Xirema Actually no guarantee that the epoch of high_resolution_clock is bound to system start. This is just a possible monotonic implementation. All that high_resolution_clock guarantees is that it is the fastest available clock. Could be system time, could be a monotonic counter, could be a hamster in a wheel. It's just fast. – user4581301 Sep 30 '15 at 20:44
  • Yeah, I'm just using system start as an example to shorten the explanation. My comments were already brushing against the character limit. – Xirema Sep 30 '15 at 20:46
1

With the exception of using boost::chrono, I am not aware of any system independent method. I have implemented the following for windows and posix:

   LgrDate LgrDate::gmt()
   {
      LgrDate rtn;
#ifdef _WIN32
      SYSTEMTIME sys;
      GetSystemTime(&sys);
      rtn.setDate(
         sys.wYear,
         sys.wMonth,
         sys.wDay);
      rtn.setTime(
         sys.wHour,
         sys.wMinute,
         sys.wSecond,
         sys.wMilliseconds*uint4(nsecPerMSec));
#else
      struct timeval time_of_day;
      struct tm broken_down;
      gettimeofday(&time_of_day,0);
      gmtime_r(
         &time_of_day.tv_sec,
         &broken_down);
      rtn.setDate(
         broken_down.tm_year + 1900,
         broken_down.tm_mon + 1,
         broken_down.tm_mday);
      rtn.setTime(
         broken_down.tm_hour,
         broken_down.tm_min,
         broken_down.tm_sec,
         time_of_day.tv_usec * nsecPerUSec);
#endif
      return rtn;
   } // gmt
Jon Trauntvein
  • 4,453
  • 6
  • 39
  • 69
0

On a POSIX system I would do

#include <sys/time.h>
#include <sys/resource.h>

struct timespec tspec;
clock_gettime(CLOCK_REALTIME, &tspec);
int sec = (int) tspec.tv_sec;
int msec = (int) ((double) tspec.tv_nsec) / 1000000.0;

Note, CLOCK_REALTIME is used to get the wall clock, which is adjusted using NTP

and then use whatever you have for the h:m:s part

Jens Munk
  • 4,627
  • 1
  • 25
  • 40