Boost logo

Boost :

Subject: Re: [boost] [gsoc 2013] draft proposal for chrono::date
From: Vicente J. Botet Escriba (vicente.botet_at_[hidden])
Date: 2013-05-04 19:33:59


Le 04/05/13 23:09, Howard Hinnant a écrit :
> Thanks. I'm curious about some of your semantics...
>
> On May 4, 2013, at 4:15 PM, "Vicente J. Botet Escriba" <vicente.botet_at_[hidden]> wrote:
>
>> I have just extracted from my current interface some of the functions that we could have in a full featured date class.
Glad to see that we can start to talk of concrete things.
>>
>> class date;
>>
>> date today();
> In what timezone?
UTC
>
>> class date {
> What is the range of validity? Proleptic gregorian or auto-coverting to julian?
[year(-32767)/jan/1 thru year(32767)/dec/31]

Proleptic gregorian

>
> What is the internal representation?
I'm not talking here of a concrete date class yet, but much more of an
archetype of Date concept. We could see the if it is better to make
concrete classes that provide less as not efficient.
>
>> public:
>> // construct/copy/destruct
>> date(); // |year(0)/jan/1|
>> date(year, month, day);
>> date(year, month, day, no_check_t);
> Do the year, month and day types range check?
Let me say for the time been that the re is no check.
> Is the conversion from int to year implicit or explicit?
explicit.
> Is there a conversion from year to int? And if so, explicit or implicit?
yes implicit.
>
>> // and all the usual combinations
>> bool set_if_valid_date(year, month, day);
> Return true if was set?
Yes.
>
>> day day() const; // or explict operator day(); the same for the other accessors.
> I've been experimenting with the explicit operator too. Haven't decided whether or not I like it yet.
Neither me.
>
>> month month() const;
>> year year() const;
>>
>> date(year, week, weekday);
>> date(year, week, weekday, no_check_t);
>> bool set_if_valid_date(year, week, weekday);
>> week week() const;
>> weekday weekday() const;
>>
>> date(year, day_of_year);
>> date(year, day_of_year, no_check_t);
>> bool set_if_valid_date(year, day_of_year);
>> day_of_year day_of_year() const;
>>
>> explicit date(days);
>> date(days, no_check_t);
>> bool set_if_valid_date(days);
>> days days_since_epoch(); // or time_since_epoch() or just days()
> Is the epoch specified or left unspecified?
specified.

year(0)/jan/1

>
>> explicit date(system_clock::time_point);
>> operator system_clock::time_point() const;
> Do the above two assume the UTC timezone?
Copy/paste from your original proposal.

explicit date(chrono::system_clock::time_point tp);

    /Effects:/ |tp| is converted to UTC, and then trucated to 00:00:00
    hours. A |date |is created which reflects this point in time.

    /Throws:/ If the conversion from |tp| overflows the range of |date|,
    throws an exception of type |bad_date|.

explicit operator chrono::system_clock::time_point () const;

    /Returns:/ A |chrono::system_clock::time_point| which represents the
    date referred to by |*this| at 00:00:00 UTC.

    /Throws:/ If the conversion to |tp| overflows the range of
    |chrono::system_clock::time_point|, throws an exception of type
    |bad_date|.

>
>> bool is_valid() const;
>> bool is_leap_year() const;
>>
>> date & operator+=(days);
>> date & operator++();
>> date operator++(int);
>> date & operator-=(days);
>> date & operator--();
>> date operator--(int);
>> date & operator+=(months);
>> date & operator-=(months);
> What semantics do you use for month arithmetic?
For non-contextual dates (absolute) increase the month(module 12) and
carry on the year and throw exception if the resulting date is invalid.
>
>> date & operator+=(years);
>> date & operator-=(years);
> What semantics do you use for year arithmetic?
For non-contextual dates (absolute) increase the year and throw
exception if the resulting date is invalid.
>
>> // friend functions
>> friend date operator+(date, days);
>> friend date operator+(days, date);
>> friend date operator-(date, days);
>> friend days operator-(date, date);
>> friend date operator+(date, months);
>> friend date operator+(months, date);
>> friend date operator-(date, months);
>> friend date operator+(date, years);
>> friend date operator+(years, date);
>> friend date operator-(date, years);
>> friend bool operator==(const date &, const date &);
>> friend bool operator<(const date &, const date &);
>> friend bool operator!=(const date &, const date &);
>> friend bool operator>(const date &, const date &);
>> friend bool operator<=(const date &, const date &);
>> friend bool operator>=(const date &, const date &);
>>
>> };
> I'm not seeing the ability to get the number of days in the current month, aside from building my own table and indexing into it with the month() accessor.
I have not written all the song. This could be added as I added is_leap.
I added explicitly is_leap as some date representations could choose to
store if the year is leap or not (in particular some of yours
implementation do it). The class year has some useful functions that
can be used by someone writing its own date class.

class year : public bounded< year_tag,-32768, 32767> // defines
value(), is_valid(), ...
{
public:
   // construct/copy/destruct
   explicit year(int); // no check

   // public member functions
   days days_in() const; // number of days in this year
   days days_in(month) const; // number of days in this month for year
   days days_since_epoch() const; // number of days since the epoch
   bool is_leap() const; // whether is a leap year
};

So yes we could provide a days_in_month() function defined as
dt.year().days_in(dt.month()).

Best,
Vicente


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