I have been reading with interest this thread, but have been sitting on my hands until now. After all this is a gsoc project for Anurag, not for me or anyone else.
But as long as everyone seems free to throw in their design preferences, I will add mine, several of which I've already seen repeated here, but some not.
Unchecked interface:
--------------------
date(year y, month m, day d);
This is the only order, there is no checking, the year, month and date objects do no validation themselves. They exist only to disambiguate the order of this low level constructor. This single order is chosen above any other because of the ISO standards. The use of the year, month and day objects add some type safety with no run time overhead, and so are acceptable. Each of these objects will *explicitly* convert from int:
date(year(2013), month(5), day(3)); // ok
date(2013, 5, 3); // compile time error
I dislike the use of no_check_t at this level because I see it as unnecessarily verbose and ugly, and I'll have to look up how to spell it every time I use it (see the checked interface for why).
Checked interface:
------------------
I like the use of factory functions here. I also like an easy-to-remember, convenience, forgiving, type-safety. My still-preferred spelling for the factory functions (yes, more than 1) is:
date d = year(2013) / month(5) / day(3);
date d = year(2013) / month(5) / 3;
date d = month(5) / day(3) / year(2013);
date d = month(5) / day(3) / 2013;
date d = day(3) / month(5) / year(2013);
date d = day(3) / month(5) / 2013;
These 3 orders are chosen among the possible 6 because these are the 3 that people actually use:
http://en.wikipedia.org/wiki/Date_format_by_country
The first two units have to explicit. The last unit can be implicit. Other rules are possible, but this one is a nice compromise between convenience and simplicity. It is an easy rule to remember, and the rule is easily checked by the compiler at compile time.
I like this spelling of the checked factory function over:
make_unchecked_date(2013, may, 3);
or
make_valid_date(2013, may, 3);
because I know I will remember how to spell the former 3 years from now, but I will have to look the latter up in a reference, unless I'm dealing with dates often enough that I memorize it.
In both interfaces, the year, month and day objects do no validity checking. The validity checks in the checked interface happen only at the time the full date is constructed.
-----------------
Two date types:
1. Serial:
typedef duration