Boost logo

Boost :

Subject: Re: [boost] [gsoc 2013] draft proposal for chrono::date
From: Anders Dalvander (boost_at_[hidden])
Date: 2013-05-07 17:32:44


On 2013-05-06 05:29, Howard Hinnant wrote:
>
> Btw, I'm getting better at this (speaking of manual dexterity more than coding):
>
> day_point d = year(2013) / may / day(5);
> auto t = hours(22) + minutes(55) + seconds(55);
> auto dt = d + t;
> auto EDT = -hours(4);
> dt -= EDT;
> auto dt_now = system_clock::now();
> auto diff = dt_now - dt;
> std::cout << duration_cast<milliseconds>(diff).count() << " ms\n";
>
> Output:
>
> 318 ms
>
> -------------------------
>
> My point in this post is that we have an existing std::chrono date_time facility and it would be good to interoperate with it. Dissecting this code line by line:
>
> day_point d = year(2013) / may / day(5);
>
> d is a std::chrono::time_point with the same epoch as std::chrono::system_clock::time_point, but has a much coarser resolution (technically day_point::period): std::ratio<86400>.
>
> Because d has the same epoch as system_clock::time_point, the two types can, by C++11 rules, have arithmetic together. You can subtract one from the other and it just works. The result is a std::chrono::duration with the precision of the common_type of the two precisions (typically the finer).
>
> So, the above code is proposed. But much of the following code is simply existing C++11, showing interoperability with the proposed code with C++11.
>
> auto t = hours(22) + minutes(55) + seconds(55);
>
> Nothing new about the above code. This is just a std::chrono::duration with a resolution of seconds. It exists today.
>
> auto dt = d + t;
>
> The proposal is that d has type time_point<system_clock, duration<int, ratio<86400>>>. If that is so, then it is, by C++11 rules, already legal to add such a time_point to a duration of seconds. The result is a
>
> time_point<system_clock, duration<system_clock::rep, ratio<1>>>
>
> I.e. the result is a time_point with the same epoch as system_clock. A rep capable of holding the union of values from both d and t, and a precision capable of holding both all values from d and all values from t. In English: dt is a count of seconds from the system_clock epoch ... all by C++11 specification. Nothing invented here except day_point in the first line.
>
> auto EDT = -hours(4);
>
> This is just C++11. A duration type. It could have any units: hours, minutes, seconds, whatever.
>
> dt -= EDT;
The above statement is the one which troubles me. Before executing the
statement `dt` is supposedly in EDT, and after the statement has
executed `dt` is in UTC (or is it the other way around). Anyway `dt` is
of type `time_point<system_clock, duration<system_clock::rep,
ratio<1>>>` as you wrote, but that type has a defined meaning. Each
`time_point` is a single point in time, an instant. If we start to make
exceptions to this rule, then we're back with the problems of
`boost::date_time::ptime`.

And what about the `system_clock::to_time_t` and
`time_point::time_since_epoch` functions? Shouldn't it be possible to
call them at any given time and not worry if someone has adjusted the
time_point to be in the "correct" timezone?

This is one of the things that I hoped the chrono library would solve by
requiring the user to explicit.

The C-library is this explicit, why shouldn't the chrono library be able
to be explicit as well?

> As dt is a timePoint with precision seconds, as long as the UTC offset does not have finer precision than seconds, this just works according to existing C++11 time_point arithmetic.
>
> auto dt_now = system_clock::now();
>
> The above line is straight out of C++11. Nothing new here.
>
> auto diff = dt_now - dt;
>
> Since dt_now and dt are both time_points based on system_clock, this is also straight out of C++11. Arithmetic between the two time_points is well defined by C++11, and results in a duration with a precision of the finer of the two time_points (typically that of system_clock::time_point, which for me has a precision of microseconds).
>
> std::cout << duration_cast<milliseconds>(diff).count() << " ms\n";
>
> For me this is just a simple C++11 cast of microseconds to milliseconds.
>
> -------------------------
>
> In summary: If the serial date type is nothing more than a time_point<system_clock, duration<int, ratio<86400>>>, then we get a great deal of interoperability with the C++11 time_point/duration facilities for free. And with absolutely no loss in performance. We get at no cost serial date types and serial date_time types. And the only invention needed is the field types, and the interaction between the invented field types, and the already standardized serial types.

Yes, we get a great deal of interoperability for free, for sure, but I
worry that all the implicit casting will be an even larger debt.

Regards,
Anders Dalvander


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk