
On Apr 24, 2004, at 9:35 AM, Jeff Garland wrote:
On Fri, 23 Apr 2004 23:22:34 -0400, Daryle Walker wrote
[NOTE: I haven't worked on this library; I'm just going by the posts I see here.]
For this increment/decrement by a month problem, is there any way to store a date with only a month resolution? Nothing smaller will be stored, so day crossovers won't be a problem.
I think what you mean is a 'duration' with month resolution. Ala months m1(3); months m2(2); months m3 = m2 + m1; //...
This can be done, but the issue is that to work with the date timepoint calculation is done at single day resolution. And there isn't a fixed number of days in a month, so you CANNOT say: days dd(28) == months(1); //proposition 1
Similarly the following is NOT true: days dd(365) == years(1); //proposition 2
Conversly, you can always say this: days dd(28) == weeks(4);
So the problem is while a week is a fixed length that is well known to be 7 days, a month and year are not. The length of a month and year depends on the context of the date. So people want the following sort of behavior: date d1 += months(12); //if d1 is a leap year add 366 days instead of 365
I've also only been skimming the date-time += month issue. I have an hobbyist's interest in the subject having lovingly crafted and maintained a date class of my own over the last decade (hasn't everybody! :-) ). Fwiw, here's what I'm currently doing, and it was inspired by reading the discussion in boost. When I back-fitted my revised date class into my existing applications (holiday/birthday reminder, mortgage computations, and the ever important stock option calculator!) the transition was very smooth. Of course what I'm using dates for is just tinker-toy stuff compared to a commercial quality date-aware app so please take this for what it's worth... gregorian::date can not hold an invalid date. If an attempt is made to create or assign to a gregorian::date with a value that would result in an invalid date, a gregorian::bad_date exception is thrown. Months can be added to dates, but may result in an invalid date (throwing an exception): date = mar/31/2004; date += month(1); // error! bad_date thrown, date uneffected However mar/31/2004 can also be specified with "last": date = mar/last/2004; date += month(1); // ok, apr/30/2004 mar/31/2004 == mar/last/2004 but the latter is tagged with extra information that implies the semantics of "last day of the month" rather than "31st day of the month". Similarly for adding years: date = feb/29/2004; date += year(1); // error, bad_date thrown but: date = feb/last/2004; // same as feb/29/2004 date += year(1); // ok, feb/28/2005 The following loop prints out the last day of each month: for (date d = jan/last/2004, end = dec/last/2004; d <= end; d += month(1)) std::cout << d << '\n'; 01/31/04 02/29/04 03/31/04 04/30/04 05/31/04 06/30/04 07/31/04 08/31/04 09/30/04 10/31/04 11/30/04 12/31/04 There's similar functionality for finding the nth day-of-week of a month/year, or the last day-of-week of a month/year. for (date d = last*sat/jan/2004, end = last*sat/dec/2004; d <= end; d += month(1)) std::cout << d << '\n'; 01/31/04 02/28/04 03/27/04 04/24/04 05/29/04 06/26/04 07/31/04 08/28/04 09/25/04 10/30/04 11/27/04 12/25/04 I'm currently using 64 bits to implement this (sizeof(date) == 8 on a 32 bit machine). I'd be happy to share more details if there is interest. This is just a hobby for me. I'm not trying to write the "date class that satisfies the world". I'm satisfied and in hobbies that's all that counts. :-) -Howard