
Rob Stewart wrote:
From: David Abrahams <dave@boost-consulting.com>
"Jeff Garland" <jeff@crystalclearsoftware.com> writes:
On Wed, 14 Apr 2004 13:04:34 +0100, Val Samko wrote
Does that mean that add_month won't be implemented? What if we call it inc_month, instead of add_month? inc_month (Increase Month) in no way assumes that the day of the month will stay the same, it will just increase the month.
Yes, perhaps a different name would help eliminate any confusion that we are doing 'math' here.
I think readability is more important. Nobody but pedants have problems with string + string. Likewise I think:
d + 2*months
or whatever is better than the functional-looking alternatives.
If there was universal acceptance of what it means to add two months to a date, I might agree. Given the imprecise notion of what it means to add two months, however, I disagree. "next_month" or "increment_month" versus "add_month" better distinguish the imprecision.
Here I totally agree with Rob, adding months is a non-intuitive operation and calling out the precision helps the readability of the program. It makes perfect sense to do d + (30 * days) but not with Months. Yours, -Gary-

"Powell, Gary" <powellg@amazon.com> writes:
I think readability is more important. Nobody but pedants have problems with string + string. Likewise I think:
d + 2*months
or whatever is better than the functional-looking alternatives.
If there was universal acceptance of what it means to add two months to a date, I might agree. Given the imprecise notion of what it means to add two months, however, I disagree. "next_month" or "increment_month" versus "add_month" better distinguish the imprecision.
Here I totally agree with Rob, adding months is a non-intuitive operation and calling out the precision helps the readability of the program.
It makes perfect sense to do
d + (30 * days)
but not with Months.
It makes perfect sense if you know the semantics the library assigns to months. Does the library have a concept of a month with no day, e.g. January of 2004? If so, I'd be happy to say date(d.month() + 2*months, d.day) That, too, calls out the fact that adding months to dates has a dubious meaning. -- Dave Abrahams Boost Consulting http://www.boost-consulting.com

David Abrahams <dave@boost-consulting.com> writes:
"Powell, Gary" <powellg@amazon.com> writes:
I think readability is more important. Nobody but pedants have problems with string + string. Likewise I think:
d + 2*months
or whatever is better than the functional-looking alternatives.
If there was universal acceptance of what it means to add two months to a date, I might agree. Given the imprecise notion of what it means to add two months, however, I disagree. "next_month" or "increment_month" versus "add_month" better distinguish the imprecision.
Here I totally agree with Rob, adding months is a non-intuitive operation and calling out the precision helps the readability of the program.
It makes perfect sense to do
d + (30 * days)
but not with Months.
It makes perfect sense if you know the semantics the library assigns to months.
Does the library have a concept of a month with no day, e.g. January of 2004? If so, I'd be happy to say
date(d.month() + 2*months, d.day)
That, too, calls out the fact that adding months to dates has a dubious meaning.
No comment? -- Dave Abrahams Boost Consulting http://www.boost-consulting.com

From: David Abrahams <dave@boost-consulting.com>
David Abrahams <dave@boost-consulting.com> writes:
"Powell, Gary" <powellg@amazon.com> writes:
Rob Stewart <stewart@sig.com> writes:
I think readability is more important. Nobody but pedants have problems with string + string. Likewise I think:
d + 2*months
or whatever is better than the functional-looking alternatives.
If there was universal acceptance of what it means to add two months to a date, I might agree. Given the imprecise notion of what it means to add two months, however, I disagree. "next_month" or "increment_month" versus "add_month" better distinguish the imprecision.
Here I totally agree with Rob, adding months is a non-intuitive operation and calling out the precision helps the readability of the program.
It makes perfect sense to do
d + (30 * days)
but not with Months.
It makes perfect sense if you know the semantics the library assigns to months.
A maintenance programmer, may infer any meaning that seems personally meaningful to such expressions. Sure, that programmer would be wrong to make assumptions, but given that adding 2 * months could mean any of a number of things, for which there isn't complete agreement, it makes such syntactic sugar dangerous.
Does the library have a concept of a month with no day, e.g. January
I don't know.
of 2004? If so, I'd be happy to say
date(d.month() + 2*months, d.day)
That, too, calls out the fact that adding months to dates has a dubious meaning.
That makes the result of the expression quite explicit. I can't see any problems with that approach. I'd expect an exception if the resulting month doesn't have the requested day. OTOH, if date's ctor were to take an extra argument, or if there was a date factory function supplying the different behavior, you could specify that you want clipping to the last day of the designated month: date(d.month() + 2 * months, d.day(), clip_to_eom) make_date_clipped_to_end_of_month(d.month() + 2 * months, d.day())
No comment?
I read it before, but you made me take another look. I guess I had something to say after all. -- Rob Stewart stewart@sig.com Software Engineer http://www.sig.com Susquehanna International Group, LLP using std::disclaimer;

Rob Stewart <stewart@sig.com> writes:
of 2004? If so, I'd be happy to say
date(d.month() + 2*months, d.day)
That, too, calls out the fact that adding months to dates has a dubious meaning.
That makes the result of the expression quite explicit. I can't see any problems with that approach. I'd expect an exception if the resulting month doesn't have the requested day. OTOH, if date's ctor were to take an extra argument, or if there was a date factory function supplying the different behavior, you could specify that you want clipping to the last day of the designated month:
date(d.month() + 2 * months, d.day(), clip_to_eom) make_date_clipped_to_end_of_month(d.month() + 2 * months, d.day())
Yes. -- Dave Abrahams Boost Consulting http://www.boost-consulting.com

Rob Stewart writes:
That makes the result of the expression quite explicit. I can't see any problems with that approach. I'd expect an exception if the resulting month doesn't have the requested day. OTOH, if date's ctor were to take an extra argument, or if there was a date factory function supplying the different behavior, you could specify that you want clipping to the last day of the designated month:
date(d.month() + 2 * months, d.day(), clip_to_eom) make_date_clipped_to_end_of_month(d.month() + 2 * months, d.day())
IMHO, simple date wrappers can give more readability: d.allow_clipping_to_eom() + 2*months; d.disallow_clipping_to_eom() + 2*months; or allow_clipping_to_eom(d) + 2*months; disallow_clipping_to_eom(d) + 2*months; where adding months to date directly isn't allowed. Regards, Janusz

"Janusz Piwowarski" <jpiw@go2.pl> writes:
Rob Stewart writes:
That makes the result of the expression quite explicit. I can't see any problems with that approach. I'd expect an exception if the resulting month doesn't have the requested day. OTOH, if date's ctor were to take an extra argument, or if there was a date factory function supplying the different behavior, you could specify that you want clipping to the last day of the designated month:
date(d.month() + 2 * months, d.day(), clip_to_eom) make_date_clipped_to_end_of_month(d.month() + 2 * months, d.day())
IMHO, simple date wrappers can give more readability:
d.allow_clipping_to_eom() + 2*months; d.disallow_clipping_to_eom() + 2*months;
or
allow_clipping_to_eom(d) + 2*months; disallow_clipping_to_eom(d) + 2*months;
where adding months to date directly isn't allowed.
That said, I'd really like to de-emphasize the importance of this clipping behavior. We already have a plausible way to represent a particular month, e.g. Feb/2003. I'd like to be able to write: 30/(Feb/2003 + 3*month) To get 30/May/2003. Cheers, -- Dave Abrahams Boost Consulting http://www.boost-consulting.com

From: David Abrahams <dave@boost-consulting.com>
That said, I'd really like to de-emphasize the importance of this clipping behavior. We already have a plausible way to represent a
Agreed.
particular month, e.g. Feb/2003. I'd like to be able to write:
30/(Feb/2003 + 3*month)
To get 30/May/2003.
I like it, but I'm not sure I'm seeing in that what you meant. If May were an enumerator of type boost::gregorian::months, or whatever, then: day_and_month operator /(greg_day, months) { return day_and_month(greg_day, months); } date operator /(day_and_month d_m, greg_year y) { return date(y, d_m.month, d_m.day); } date operator /(greg_day d, month_and_year m_y) { return date(m_y.year, m_y.month, day); } month_and_year operator /(months, greg_year) { return month_and_year(months, greg_year); } plus operators for adding 3*month to a month_and_year should allow: date d(30/May/2003); d = 30/(Feb/2003 + 3*month); -- Rob Stewart stewart@sig.com Software Engineer http://www.sig.com Susquehanna International Group, LLP using std::disclaimer;

David Abrahams writes:
We already have a plausible way to represent a particular month, e.g. Feb/2003. I'd like to be able to write:
30/(Feb/2003 + 3*month)
To get 30/May/2003.
Slash isn't normal date separator in all countries. Anyhow, i like it. Janusz.

Janusz Piwowarski wrote:
We already have a plausible way to represent a particular month, e.g. Feb/2003. I'd like to be able to write:
30/(Feb/2003 + 3*month)
To get 30/May/2003.
Slash isn't normal date separator in all countries. Anyhow, i like it.
Once again, I suggest to use a syntax closer to ISO 8601: 2003-MAY-30 Should IMHO be the most international representation we can find. Regards, Daniel -- Daniel Frey aixigo AG - financial solutions & technology Schloß-Rahe-Straße 15, 52072 Aachen, Germany fon: +49 (0)241 936737-42, fax: +49 (0)241 936737-99 eMail: daniel.frey@aixigo.de, web: http://www.aixigo.de

On Tue, 20 Apr 2004 10:54:35 +0200, Daniel Frey wrote
Janusz Piwowarski wrote:
We already have a plausible way to represent a particular month, e.g. Feb/2003. I'd like to be able to write:
30/(Feb/2003 + 3*month)
To get 30/May/2003.
Slash isn't normal date separator in all countries. Anyhow, i like it.
Once again, I suggest to use a syntax closer to ISO 8601:
2003-MAY-30
Which, of course, isn't iso 8601 either because months in 8601 are never character strings. But I do happen to like your format better as I believe it is clearer then the 8601 standard :-) No confusion about which part is the month.
Should IMHO be the most international representation we can find.
I believe what they are talking about is an expression template representation which is limited by c++ operators. My problem with this (as I said in the other thread) is that expressions with fixed dates in code is a minor case in my experience. Most of these expressions in real apps would use dates serialized from files and databases -- not embedded in c++ code. In files and databases we want something that is more standard, which the library already supports. Jeff

Jeff Garland wrote:
To get 30/May/2003.
Slash isn't normal date separator in all countries. Anyhow, i like it.
Once again, I suggest to use a syntax closer to ISO 8601:
2003-MAY-30
Which, of course, isn't iso 8601 either because months in 8601 are never
Obviously, which is why I wrote "closer to" not "according to" :)
character strings. But I do happen to like your format better as I believe it is clearer then the 8601 standard :-) No confusion about which part is the month.
And indeed the '-' hopefully reminds people that it's not their local format that they are using.
Should IMHO be the most international representation we can find.
I believe what they are talking about is an expression template representation which is limited by c++ operators. My problem with this (as I said in the other thread) is that expressions with fixed dates in code is a minor case in my experience. Most of these expressions in real apps would use dates serialized from files and databases -- not embedded in c++ code. In files and databases we want something that is more standard, which the library already supports.
Of course, the above is just syntactic sugar and not really required (but hey, it's cool, isn't it :). And FWIW I often use fixed dates in my code when punching together some test data. Regards, Daniel -- Daniel Frey aixigo AG - financial solutions & technology Schloß-Rahe-Straße 15, 52072 Aachen, Germany fon: +49 (0)241 936737-42, fax: +49 (0)241 936737-99 eMail: daniel.frey@aixigo.de, web: http://www.aixigo.de

On Tue, 20 Apr 2004 14:13:20 +0200, Daniel Frey wrote
Of course, the above is just syntactic sugar and not really required (but hey, it's cool, isn't it :). And FWIW I often use fixed dates in my code when punching together some test data.
Sure it's cool, until you have to write the docs and explain a feature to average programmers, twice -- since there is the ET way and the normal way. Jeff

Daniel Frey <daniel.frey@aixigo.de> writes:
Janusz Piwowarski wrote:
We already have a plausible way to represent a particular month, e.g. Feb/2003. I'd like to be able to write:
30/(Feb/2003 + 3*month)
To get 30/May/2003. Slash isn't normal date separator in all countries. Anyhow, i like it.
Once again, I suggest to use a syntax closer to ISO 8601:
2003-MAY-30
Should IMHO be the most international representation we can find.
Regards, Daniel
I forgot about the standard use of "-". IMO we should allow both usages, because some people may find 2003-MAY-30 - 10 confusing. I disagree, as well, with using an ALL_CAPS identifier for months. Probably should be 2003-may-30 -- Dave Abrahams Boost Consulting http://www.boost-consulting.com

Sorry to not be able to keep up with this in real-time. Since I haven't, let me try to summarize. I've responded to a few discussions independent of this email. 1) There is broad agreement that the library should offer functions for adding months. If for no other reason than the complexity of the issue as demonstrated by this email thread. 2) There is no overall consensus for the best name and form of these function(s). Sticking with the pure function names for a moment, Rob and others suggested the following names: next_month increment_month Just as a note, the JAVA library calls this 'roll' -- which doesn't quite do it for me, but just offering other altenatives. http://java.sun.com/j2se/1.4.2/docs/api/java/util/Calendar.html 2) Behavior of 'add_month'. Ignoring the name of the function for a moment... 2a) Exceptions / not_a_date_time when adding past the end of the month: These seemed to be the least liked behaviors. 2b) Reversability One of the major concerns seems to be reversibility of calculation. I think in general this property cannot be provided with a 'logical function' unless you have a complete memory of all calculations. Needless to say, the 'date' class is not the place to provide this. This is hardly the only place in date_time where these sort of issues crop up. Once upon a time Michael Kenniston wrote up this point in some detail. It's not specific to adding months, but I believe it comes down to some of the same core issues. http://www.boost.org/libs/date_time/doc/Tradeoffs.html Bottom line, if you want reversability at the date level everything needs to be done in terms of days and weeks. Also, I believe the month_iterator provides a limited level of reversability if you need with the 'end of month snap behavior'. In 1_31 it is now bi-directional so if you iterate forward and then back you get the same month_iterator mitr(date(2000,Jan,31)); mitr++; //feb 29 -- will be feb 28 in non-leap-years mitr++; //mar 31 mitr--; //feb 29 mitr--; //Jan 31 4) Non functional alternatives Dave and I like the idea of non-functional alternatives. Gary, Rob, and Val are against it on the grounds that the non-intuitive behavior makes it dangerous. Per my 'date-generators' email, I'm still interested in this, but I think it should be built on a functional base. 5) Implementing LAST-1, LAST-2, etc At the very beginning of this thread I agreed that having functions like: date d(...);//arbitrary date date fd = first_date_of_month(d); date ld = last_date_of_month(d); would be valueable additions. LAST-2 can be trivially implemented for fully specified dates as follows: days_before_end_of_month(const date& d, days days_before) { return last_date_of_month(d) - days_before; } However, it might be useful to have another date generator which would not require a full date and could represent the last day of the month variants. I'm thinking something like: last_day_of_month ldom; date d = ldom.getDate(2003, Feb); //feb 28 before_last_day_of_month ldom(2); date d = ldom.getDate(2003, Feb); //feb 26 Jeff

From: "Jeff Garland" <jeff@crystalclearsoftware.com>
Bottom line, if you want reversability at the date level everything needs to be done in terms of days and weeks.
Right.
5) Implementing LAST-1, LAST-2, etc At the very beginning of this thread I agreed that having functions like: date d(...);//arbitrary date date fd = first_date_of_month(d); date ld = last_date_of_month(d);
would be valueable additions. LAST-2 can be trivially implemented for fully specified dates as follows:
days_before_end_of_month(const date& d, days days_before) { return last_date_of_month(d) - days_before; }
That generates such a date, but doesn't carry the "n days before the end of the month" concept along with it. That is, the idea was to apply the concept to any month and year pair to get "n days before the end."
However, it might be useful to have another date generator which would not require a full date and could represent the last day of the month variants. I'm thinking something like:
last_day_of_month ldom; date d = ldom.getDate(2003, Feb); //feb 28 before_last_day_of_month ldom(2); date d = ldom.getDate(2003, Feb); //feb 26
That provides the means to overload the date ctors with the concept. -- Rob Stewart stewart@sig.com Software Engineer http://www.sig.com Susquehanna International Group, LLP using std::disclaimer;

From: "Janusz Piwowarski" <jpiw@go2.pl>
Rob Stewart writes:
That makes the result of the expression quite explicit. I can't see any problems with that approach. I'd expect an exception if the resulting month doesn't have the requested day. OTOH, if date's ctor were to take an extra argument, or if there was a date factory function supplying the different behavior, you could specify that you want clipping to the last day of the designated month:
date(d.month() + 2 * months, d.day(), clip_to_eom) make_date_clipped_to_end_of_month(d.month() + 2 * months, d.day())
IMHO, simple date wrappers can give more readability:
d.allow_clipping_to_eom() + 2*months; d.disallow_clipping_to_eom() + 2*months;
That would require modifying the date class to add new mfs for each style, right? Or did you mean that "d" was of a wrapper type?
or
allow_clipping_to_eom(d) + 2*months; disallow_clipping_to_eom(d) + 2*months;
where adding months to date directly isn't allowed.
That sounds like an excellent approach. Not only might the library provide one or more such date wrappers and factory functions, but this provides a clear usage pattern that custom wrappers can follow. -- Rob Stewart stewart@sig.com Software Engineer http://www.sig.com Susquehanna International Group, LLP using std::disclaimer;

Rob Stewart writes:
d.allow_clipping_to_eom() + 2*months; d.disallow_clipping_to_eom() + 2*months;
That would require modifying the date class to add new mfs for each style, right?
Right
or
allow_clipping_to_eom(d) + 2*months; disallow_clipping_to_eom(d) + 2*months;
where adding months to date directly isn't allowed.
That sounds like an excellent approach. Not only might the library provide one or more such date wrappers and factory functions, but this provides a clear usage pattern that custom wrappers can follow.
Yes, it's possible to create rules like dont_stop_on_sunday(d) + 14*days Janusz
participants (6)
-
Daniel Frey
-
David Abrahams
-
Janusz Piwowarski
-
Jeff Garland
-
Powell, Gary
-
Rob Stewart