3

I have a timestamp representing nanoseconds since midnight. I would like to calculate the number of nanoseconds (right now) since midnight, to subtract the two timestamps and measure the latency. I would like to do this using the fastest operations.

The target platform is x86-64 Linux, Clang compiler, no old Kernel or hardware, I don't care about daylight saving, there are no round cases to cover etc.

I understand:

struct timespec now;
clock_gettime(CLOCK_REALTIME, &now);

will return the number of seconds since Epoch and the number of nanoseconds after the last second.

I therefore think I just need to create a time point representing midnight, extract the number of seconds since Epoch from midnight and then do:

now_nanos = (((now.seconds_since_epoch) - (midnight.seconds_since_epoch)) x 1 billion) + now.nanos_since_last_second

How do I create a time point representing midnight, to extract the number of seconds since Epoch?

I have seen examples using mktime() returning a time_t but I wasn't sure how to extract the seconds since Epoch?

user997112
  • 29,025
  • 43
  • 182
  • 361

1 Answers1

2

First get the current time with time. Then pass the result of that to localtime_r to get the time broken up into its components pieces. Zero out the hours, miniutes, and seconds, then use mktime to switch back to seconds since the epoch.

time_t now = time(NULL);
struct tm tm;
localtime_r(&now, &tm);
tm.tm_sec = 0;
tm.tm_min = 0;
tm.tm_hour = 0;
time_t start_of_day = mktime(&tm);
dbush
  • 205,898
  • 23
  • 218
  • 273
  • @user997112 a `time_t` holds the number of seconds since the epoch. When you convert to nanoseconds, you may want to explicitly cast to `uint64_t` to make sure you don't overflow / wraparound. – dbush Nov 18 '19 at 04:30
  • All good, thank you sir. Just waiting before I can accept your answer. – user997112 Nov 18 '19 at 04:30
  • Might as well post that here and i'll accept that too https://stackoverflow.com/questions/58905600/get-nanoseconds-since-midnight-with-the-lowest-latency – user997112 Nov 18 '19 at 04:46
  • On days when DST switches, this approach can fail as `now` and midnight may exist with different `.is_dst` settings. Even though OP says "I don't care about daylight saving,", setting `tm.tm_isdst = -1;` prior to `mktime()` is a good mitigating step. – chux - Reinstate Monica Nov 18 '19 at 05:17
  • @chux-ReinstateMonica Why would tm.tm_isdst = -1 mitigate that? How does it work? – user997112 Nov 19 '19 at 03:44
  • @user997112 `.tm_isdst`: [a negative value means that mktime() should (...) attempt to determine whether DST is in effect at the specified time..](http://man7.org/linux/man-pages/man3/ctime.3.html) – chux - Reinstate Monica Nov 19 '19 at 03:46