Boost logo

Boost :

Subject: Re: [boost] [gsoc 2013] chrono::date
From: Anurag Kalia (anurag.kalia_at_[hidden])
Date: 2013-04-26 17:43:41


> One can then, taking the current definition of the civil (gregorian) calendar, create several more units which can be quite useful: > > There are exactly 7 days in a week: > > typedef std::chrono::duration > < > std::int32_t, std::ratio_multiply<days::period, std::ratio<7>> >> weeks; > > There are exactly 146097 days in 400 years, which could rightly be called an era: > > typedef std::chrono::duration > < > std::int32_t, std::ratio_multiply<days::period, std::ratio<146097>> >> eras; > > There are exactly 400 years in an era: > > typedef std::chrono::duration > < > std::int32_t, std::ratio_divide<eras::period, std::ratio<400>> >> years; > > And there are exactly 12 months in a year: > > typedef std::chrono::duration > < > std::int32_t, std::ratio_divide<years::period, std::ratio<12>> >> months; > > Now the definitions of years and months must be understood to be the average length, when converted to other units. But this is not so different than days being 24 hours: this is an average length of a day. This is almost magical! This definition of years gives me 43 years as the time since epoch, which is correct! Now given that these units are not the conventional duration of years or months, I don't think we benefit from exposing them to public, do we? Can we use these units in implementation when converting from JDN to Gregorian date? A user would want to use the construct year to either make a date where it would be an integer, or she/he would want to increment/decrement a date by a certain number of years, where it would be a duration. But we can provide them this functionality using a function and thereby not exposing this approximate year duration. If she/he happens to output an year otherwise, it would print 365.2425 which would only serve to confuse them, no? > No one is concerned that an average month is precisely 2,629,746 seconds long. However being able to say: > > assert(round<months>(jul/first/2013 - jan/first/2012).count() == 18); > > is arguably quite useful. Many financial calculations are done by the month (e.g. loan interest), even though the unit of "month" isn't as precisely defined as say "second". But with a round function things could "just work". > > template <class To, class Rep, class Period> > To > round(const std::chrono::duration<Rep, Period>& d) > { > To t0 = std::chrono::duration_cast<To>(d); > To t1 = t0; > ++t1; > auto diff0 = d - t0; > auto diff1 = t1 - d; > if (diff0 == diff1) > { > if (t0.count() & 1) > return t1; > return t0; > } > else if (diff0 < diff1) > return t0; > return t1; > } > > I'm not positive, but I believe the latest C++14 additions would allow us to mark round with constexpr, making it that much more useful. For example we could then: > > static_assert(round<months>(jul/first/2013 - jan/first/2012).count() == 18, "Better be true!"); > > Howard I haven't compiled it yet, and I would report back with my findings, thank you! Thanks a lot for the support. I have uploaded a draft proposal to this Mailing List. Would you kindly check it for me? I am not sure if I should upload it twice. Thanks, Anurag.


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