Reputation: 30635
I wrote the below code to get the number of seconds since midnight.
However, I'm not great with the C time date structs. Is there a simpler way of doing this using a standard C++ library?
// Get today's date
time_t aTime = time(NULL);
// Set the time to midnight
struct tm* tm = localtime(&aTime);
tm->tm_sec = 0;
tm->tm_min = 0;
tm->tm_hour = 0;
tm->tm_isdst = -1;
time_t midnight = mktime(tm);
// Create object representing now
struct timespec now;
clock_gettime(CLOCK_REALTIME, &now);
// Number of seconds (now) since Epoch
const uint64_t nowSecsSinceEpoch = now.tv_sec;
// Number of seconds (now) since midnight = seconds (now) since Epoch minus seconds (at midnight) since Epoch
const uint64_t nowSecsSinceMidnight = nowSecsSinceEpoch - midnight;
Upvotes: 10
Views: 3461
Reputation: 219245
It depends on if you mean time since midnight UTC, or time since midnight local time, or perhaps in some non-local, far away time zone.
This is also made much easier in C++20. But there exists a preview of the C++20 parts of the <chrono>
library that can be used with C++11-17.
#include <chrono>
#include <iostream>
int
main()
{
using namespace std;
using namespace std::chrono;
auto now = system_clock::now();
auto today = floor<days>(now);
auto tod = duration_cast<seconds>(now - today);
}
This simply gets the current time (UTC), truncates it to a days-precision time_point
, and then subtracts the two and truncates that difference to seconds precision.
#include <chrono>
#include <iostream>
int
main()
{
using namespace std;
using namespace std::chrono;
auto now = current_zone()->to_local(system_clock::now());
auto today = floor<days>(now);
auto tod = duration_cast<seconds>(now - today);
}
This version finds your computer's currently set local time zone, and then gets the current local time via the time_zone's to_local()
member function. And then proceeds as before.
#include <chrono>
#include <iostream>
int
main()
{
using namespace std;
using namespace std::chrono;
auto now = locate_zone("Australia/Sydney")->to_local(system_clock::now());
auto today = floor<days>(now);
auto tod = duration_cast<seconds>(now - today);
}
Finally, this version finds the time_zone associated with Sydney Australia, and then uses that time zone and proceeds as before.
The C++20 preview <chrono>
library is free and open-source. It puts everything in namespace date, and in two headers (and one source):
date.h
: A header-only library that will do the UTC part, but has no time zone support.
tz.h
: For the time zone support. This requires some installation.
Upvotes: 7