Boost logo

Boost :

Subject: Re: [boost] [gsoc 2013] draft proposal for chrono::date
From: Howard Hinnant (howard.hinnant_at_[hidden])
Date: 2013-05-05 23:29:50


On May 5, 2013, at 1:37 PM, Howard Hinnant <howard.hinnant_at_[hidden]> wrote:

> On May 5, 2013, at 1:09 PM, Anders Dalvander <boost_at_[hidden]> wrote:
>
>> Sorry about that, should be:
>>
>> chrono::date d = year(2013) / may / day(5);
>> chrono::time t = hours(12) + minutes(34) + seconds(56);
>> chrono::date_time dt(d, t);
>> // Here `dt` should be the representation of May 5th 2013 at 12:34:56, but that in turn occurred at different instants for different people around the world.
>> // In order to convert it to a `chono::system_clock::time_point` a timezone would be needed:
>> chono::system_clock::time_point instant = dt.in_timezone(chrono::timezones::utc); // or perhaps `dt.in_utc()` for short.
>
> Fwiw, I just ran this program fragment:
>
> day_point d = year(2013) / may / day(5);
> auto t = hours(13) + minutes(34) + seconds(30);
> 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<seconds>(diff).count() << " seconds\n";
>
> And it output:
>
> 1 seconds

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;

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.

Howard


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