We are going to save the current time and print it. Additionally, our program will add different offsets to the saved time point and print the resulting time points too:
- The typical include lines come first; then, we declare that we use the std namespace by default:
#include <iostream>
#include <iomanip>
#include <chrono>
using namespace std;
- We are going to print absolute time points. These will come along in the form of the chrono::time_point type template, so we will just overload the output stream operator for it. There are different ways to print the date and/or time part of a time point. We will just use the %c standard formatting. We could, of course, also print only the time, only the date, only the year, or whatever comes to our mind. All the conversions between the different types before we can finally apply put_time look a bit clunky, but we are only doing this once:
ostream& operator<<(ostream &os,
const chrono::time_point<chrono::system_clock> &t)
{
const auto tt (chrono::system_clock::to_time_t(t));
const auto loct (std::localtime(&tt));
return os << put_time(loct, "%c");
}
- There are already STL type definitions for seconds, minutes, hours, and so on. We will add the days type now. This is easy; we just have to specialize the chrono::duration template by referring to hours and multiply with 24, because a full day has 24 hours:
using days = chrono::duration<
chrono::hours::rep,
ratio_multiply<chrono::hours::period, ratio<24>>>;
- In order to be able to express a duration in multiples of days in the most elegant way, we can define our own days literal operator. Now, we can write 3_days to construct a value that represents three days:
constexpr days operator ""_days(unsigned long long h)
{
return days{h};
}
- In the actual program, we will take a time snapshot, which we simply print afterward. This is very easy and comfortable because we already implemented the right operator overload for this:
int main()
{
auto now (chrono::system_clock::now());
cout << "The current date and time is " << now << 'n';
- Having saved the current time in the now variable, we can add arbitrary durations to it and print those too. Let's add 12 hours to the current time and print what time we will have in 12 hours:
chrono::hours chrono_12h {12};
cout << "In 12 hours, it will be "
<< (now + chrono_12h)<< 'n';
- By declaring that we use the chrono_literals namespace by default, we unlock all the existing duration literals for hours, seconds, and so on. This way, we can elegantly print what time it was 12 hours and 15 minutes ago, or 7 days ago:
using namespace chrono_literals;
cout << "12 hours and 15 minutes ago, it was "
<< (now - 12h - 15min) << 'n'
<< "1 week ago, it was "
<< (now - 7_days) << 'n';
}
- Compiling and running the program yields the following output. Because we used %c as the format string for time formatting, we get a pretty complete description in a specific format. By playing around with different format strings, we can get it in any format we like. Note that the time format is not 12 hours AM/PM but 24 hours because the app is run on a European system:
$ ./relative_absolute_times
The current date and time is Fri May 5 13:20:38 2017
In 12 hours, it will be Sat May 6 01:20:38 2017
12 hours and 15 minutes ago, it was Fri May 5 01:05:38 2017
1 week ago, it was Fri Apr 28 13:20:38 2017