4

Taking the first steps with <chrono> library, I'm starting with basic arithmetic on a days grained time_point. Thanks to a very useful post by @HowardHinnant, I managed to write this:

#include <chrono>
using namespace std::chrono_literals;

int main()
{
    std::chrono::sys_days d {std::chrono::January/31/2022};
    d += std::chrono::days{2}; // ok
    //d += 48h; // error: no match for 'operator+=' with std::chrono::hours
}

What is not clear to me is why d += 48h; isn't allowed. The std::chrono::time_point<>::operator+= takes a duration, and the rvalue in that expression is a std::chrono::hours that in my mind represents a time duration. What's the philosophy here? Are there different duration types according to the measure unit that must be compatible with the granularity of the time_point? Why?

On the other hand, I understand why d += 2d; gives an error, since in this case std::literals::chrono_literals::operator""d is a std::chrono::day, which is not a duration (that's handy to form a date literal, although it seems a little inconsistent to me). I wonder if there's a more convenient way to express a duration literal equivalent to std::chrono::days{2}.

user438383
  • 5,716
  • 8
  • 28
  • 43
MatG
  • 574
  • 2
  • 7
  • 19
  • Because resolution of `sys_days` is days and not hours, everything beyond that is lost. If you want hour granularity then use hours, or better yet, simply [std::chrono::time_point](https://en.cppreference.com/w/cpp/chrono/time_point) –  Jan 11 '22 at 09:40
  • @Sahsahae In my ingenuity I assumed that `48h` was a duration equivalent to two days, because I couldn't express it with `2d`. I chose a day granularity just to see how it worked, but it seems I have to study better the rationale behind this library. – MatG Jan 11 '22 at 10:02
  • 1
    *A more convenient way to express a duration literal equivalent to `days{2}`* — nobody can stop you from creating your own `operator""_days` – Ranoiaetep Jan 11 '22 at 13:17
  • @Ranoiaetep That's a good point that I was missing. – MatG Jan 11 '22 at 13:25
  • 1
    For the basics of durations, time_points and clocks, here's a 1h video tutorial: https://www.youtube.com/watch?v=P32hvk8b13M For a video on how calendars and timezones are built on that: https://www.youtube.com/watch?v=adSAN282YIw – Howard Hinnant Jan 11 '22 at 14:03

1 Answers1

6

You can add hours to days. What you can't do is implicitly convert that into days again. You need a cast

d = std::chrono::time_point_cast<std::chrono::days>(d + 48h);
Caleth
  • 52,200
  • 2
  • 44
  • 75
  • So the `operator+` accepts `hours`, and the result is a `time_point` in hours. I thought that `d+=48h;` was expressing a clear intent, but I see now that an implicit cast could hide a nasty unwanted behaviour. – MatG Jan 11 '22 at 13:19
  • @MatG In this case you'd be dropping a `0`, but in general it's a lossy conversion – Caleth Jan 11 '22 at 13:25