There is a hobby project that I’m doing and found myself in need of using date/time facilities available in the chrono library. My tasks at this stage are simple:
- Get the current date and time
- Get date and time beginning midnight
- Do some comparison between (1) and (2)
There are two clocks of interest in the chrono library: system_clock and steady_clock. What is a clock you may ask? Well, in this context, a clock is a time provider that has a starting point (epoch) and tick rate.
system_clock is a system-wide wall clock and it is better suited for my tasks at hand as I’m interested more in the calendrical operation. The steady clock, on the other hand, is more appropriate for stopwatch like functionality.
Most implementations use the epoch 00:00:00 Coordinated Universal Time (UTC) for system_clock.
Task 1: Get the current date and time
There is a static method available to get the current time_point:
auto current = chrono::system_clock::now();
That method returns a time_point which as the name suggests, a point in time and it is tied to the clock with respect to the duration from the epoch of the clock.
auto now_timet = chrono::system_clock::to_time_t(current);
auto now_local = localtime(&now_timet);
cout << "Local Time " << put_time(now_local, "%c") << endl;output:
Local Time Tue Apr 21 17:56:27 2020
to_time_t converts that time_point to time_t which is represented as an integral type holding number of seconds since 00:00, Jan 1, 1970, UTC.
E.g output below, if you print time_t:
cout << "As time_t " << now_timet << endl;output:
As time_t 1587506187
localtime could then take that time_t and express it in local calendar time.
Task 2: Get the date and time from midnight
For this task, I can set hours, mins and seconds to 0 in the std::tm struct.
auto midnight_local = now_local;
midnight_local->tm_hour = 0;
midnight_local->tm_min = 0;
midnight_local->tm_sec = 0;
Then convert it to number of seconds since epoch i.e. time_t by using mktime
auto midnight_timet = mktime(midnight_local);
cout << "As time_t " << midnight_timet << endl;output:
As time_t 1587441600
Let’s say, if I have persisted the time_t value and later on needs to get back the time_point for further operations, I can do so:
auto midnight = chrono::system_clock::from_time_t(midnight_timet);
Task 3: Do some comparison between (1) and (2)
I could just use the time_t or chrono::duration to make some tasks simpler. E.g.
auto diff_mins = std::chrono::duration_cast<std::chrono::minutes>(current - midnight);
auto diff_hrs = std::chrono::duration_cast<std::chrono::hours>(current - midnight);
cout << "Minutes passed since midnight " << diff_mins.count() << endl;
cout << "Hours passed since midnight " << diff_hrs.count() << endl;output:
Minutes passed since midnight 1076
Hours passed since midnight 17
My objective is to be able to query records with a field storing the time_t representation satisfying some conditions. In the example above, the condition being the ability to determine the start of the day (i.e. midnight) and now i.e. current date and time.
Howard Hinnant “A ＜chrono＞ Tutorial”: