The hard part of writing this custom clock is figuring out how to write its now()
function. In the example below I base the now()
off of system_clock
‘s now()
. First I do some detective work to discover that my system_clock
has an epoch of New Years 1970, neglecting leap seconds. This is known as unix time. As it turns out, every implementation I’m aware of (and I think I’ve checked them all) have this very same epoch (but this is unspecified by the C++11 standard).
Next I compute that 1988-07-13 is 6768 days after 1970-01-01. Using these two facts, the rest is easy:
#include <chrono>
struct My_Clock
{
typedef std::chrono::seconds duration;
typedef duration::rep rep;
typedef duration::period period;
typedef std::chrono::time_point<My_Clock> time_point;
static const bool is_steady = false;
static time_point now() noexcept
{
using namespace std::chrono;
return time_point
(
duration_cast<duration>(system_clock::now().time_since_epoch()) -
hours(6768*24)
);
}
};
MyClock
needs nested typedefs to describe its duration
, rep
, period
, and time_point
. Based on your question, I’ve chosen seconds
as the duration
, but you can choose anything you want.
For the now()
function I just call the system_clock::now()
and subtract off the epoch in units of seconds. I got just a little clever with this computation by writing everything in terms of MyClock::duration
so that I can more easily change duration
. Note that I was able to subtract off the epoch in terms of hours
, which implicitly converts to duration
(which is seconds
). Alternatively I could have built myself a custom duration
of days:
typedef std::chrono::duration<int, std::ratio_multiply<std::chrono::hours::period,
std::ratio<24>>> days;
And then the return of now()
could have been written:
return time_point
(
duration_cast<duration>(system_clock::now().time_since_epoch()) -
days(6768)
);
At any rate, now you can use this like:
#include <iostream>
int
main()
{
using namespace std::chrono;
time_point<My_Clock> tp = My_Clock::now();
std::cout << tp.time_since_epoch().count() << '\n';
}
Which for me just printed out:
786664963
Which demonstrates that today (2013-06-16) is approximately 24.9 years after 1988-07-13.
Update for C++20
In C++20 you can use the updated <chrono>
calendrical services to eliminate the “magic number” from the implementation:
#include <chrono>
struct My_Clock
{
typedef std::chrono::seconds duration;
typedef duration::rep rep;
typedef duration::period period;
typedef std::chrono::time_point<My_Clock> time_point;
static const bool is_steady = false;
static time_point now() noexcept
{
using namespace std::chrono;
return time_point
{
duration_cast<duration>(system_clock::now() - sys_days{July/13/1988})
};
}
};
There is no run-time expense for this convenience. The sub-expression sys_days{July/13/1988}
is optimized at compile-time into a count of days since the system_clock
epoch, and then further converted to system_clock::duration
(still at compile-time) before being subtracted from system_clock::now()
.