Boost logo

Boost :

Subject: [boost] [chrono/date] Two axes for a date design: validity check and representation and an essence date class/factory
From: Vicente J. Botet Escriba (vicente.botet_at_[hidden])
Date: 2013-05-07 06:46:58


Hi,

I would like to discuss about some alternatives to take in account the
following use case
  "Reset a date if it resulting date is valid and report if this succeeds"
when we have two axes of variation on the date design.

Let me add two parameters to the possible date class.
* validity: unchecked/checked
* representation: serial, ymd(calendar), iso_ordinal, iso_week...

date<serial, unchecked> is an unchecked serial date. It corresponds +/-
to the N3344 date suggestion.
date<ymd, checked> is a checked ymd date. It corresponds +/- to the H.H
2011 date proposal.

WARNING !!! I'm not saying that a template class is a good thing, it is
just to state clearly the features of the date.

N3344 suggest a date::set_if_valid_date function.

date<serial, unchecked> ud=...;
if (ud.set_if_valid_date(y,m,d)) {
  // xx
} else {
  // yy
}

But if we want to do as for the date constructors we will need multiple
overloads again for this function :(.
As show on this ML serial+unchecked dates validation could have some
surprises.
We can get the same service building a ymd date that can provide a way
to be validated.

//-------------
// Validity check done when is_valid() is called on ymd_date.

date<serial, unchecked> dd=...;
date<ymd, unchecked> yd(y,m,d);
if (yd.is_valid()) { // CHECK
   dd = yd;
// xx
} else {
  // yy
}

Instead of using explicitly date<ymd,unchecked> we can use a
make_essence() factory
that returns some kind of tuple essence_date<year,month,day> that is not
a date, but its essence. It contains everything needed to build a date.
This essence should be implicitly convertible to any date.
The make_essence_date() factory supports all the different orders of
parameters.
The operator/() expression would also create an essence date.

// --------------
//No validity check is done.

date<serial, unchecked> ud = make_essence(y,m,d);
date<serial, unchecked> ud1 = m/d/y;

This essence dates support date validity, that is provides a is_valid()
function.

// --------------
// Validity check done when is_valid() is called on essence.

date<serial, unchecked> ud;
auto d = y/m/d;
if (d.is_valid()) { // CHECK
   ud = d;
  // xx
} else {
  // yy
}

//--------------
// Validity check done at construction of cd.

serial_date<checked> cd = make_essence(m,d,y);
//serial_date<checked> cd = m/d/y;

Summary: IMO
Having checked and unchecked dates with several representations could
help to make dates interface more precise and concise.
Checked dates are always valid.
Dates with a specific representations would provide only, as suggested
by Howard, only the functions that are efficient.
The use of essence dates factories simplify the interface of all the
date classes construction. Only 1 constructor by representation needed
independent of the parameters order

   date(essence<ymd> &&);
   date(essence<serial> &&);
date(essence<iso_ordinal> &&);
date(essence<iso_week> &&);

Comments welcome,
Vicente

P.S.The essence date classes and the contextual dates are quite related.
I prefer to let this 3rd contextual axe of variation out of the current
scope. I will try to integrate it soon.


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