Peter wrote (snipped)
As far as I read ISO8601 (which also has a notation for durations) this is unspecifed :-) And as far as I read TimeExts.lhs it does some sort of rollover. My take would be to specify the behavior for adding something like a TimeDiff to a base date in a consistent manner and then cast that in stone. If there is a (reasonable) standard for this kind of calculation, then this should be the basis for the specification. OK, what TimeExts does, I hope, is add the appropriate amount of the appropriate time unit (whatever it is) directly, then rely on the CalendarTime conversions to resolve any overflows. This probably isn't very clear, so I'll give some examples of what I think ought to happen.
Add 1 month to 1st February 2003. This produces 1st March 2003. (with no overflow.) Add 1 month to 31st January 2003. Then we get 31st February 2003. This clearly requires an overflow; we note that February 2003 has 28 days, and so roll over to 3rd March 2003. Note that in this case "Add 1 month" is not a monotonic operation. Add 1 minute to 23:59:60 31st December 2003. I assume that this is a valid time and that it will be a leap second; if not choose some other year. This is complicated since we have multiple overflows. First stage you get the invalid time 23:60:60 31st December 2003. I don't know what TimeExts (or rather the CalendarTime conversions) do in this case, but what I think they *ought* to do is work from the most significant unit down, rolling around to produce a significant date at each time. When we roll around, we have to bump the next unit, and iterate. So: 2003 OK. 2003 December OK. 2003 December 31st OK. 2003 December 31st 23 OK. 2003 December 31st 23:60 NOT OK. We bump the next unit and subtract this one, then we have to iterate from the top down. So we replace 23:60 by 24:00. and get 2003 December 31st 24 not OK. Replaces "31st 24" by "32nd 00". 2003 December 32nd not OK 2003 Unidecimber (13th month) 1st not OK 2004 January OK 2004 January 1st OK 2004 January 1st 00 OK 2004 January 1st 00:00 OK 2004 January 1st 00:00:60 Not OK. Replace 00:60 by 01:00 and you eventually get 2004 January 1st 00:01:00
George> OK, what TimeExts does, I hope, is add the appropriate amount of the appropriate George> time unit (whatever it is) directly, then rely on the CalendarTime conversions to George> resolve any overflows. This probably isn't very clear, George> so I'll give some examples of what I think ought to George> happen. I see. You propose to always add the duration of the current entity. IE, a month rooted in January has 31 days, and a year rooted in a leap year has 366 days. How do you define subtraction, given that your addition is not monotonic and that you (probably) want addition and subtraction be inverses? Actually, you could equally well argue that you should always take the duration of the next following entity (in seconds, but I won't go into that detail). While this means that (in a non-leap year) January 1 + 1 month = January 29 it preserves monotonicity: January 31 + 1 month = February 28 so that you could define subtraction (although at some expense). George> Add 1 month to 1st February 2003. This produces 1st March 2003. (with no overflow.) George> Add 1 month to 31st January 2003. Then we get 31st February 2003. This clearly requires George> an overflow; we note that February 2003 has 28 days, and so roll over to 3rd March 2003. George> Note that in this case "Add 1 month" is not a monotonic operation. George> Add 1 minute to 23:59:60 31st December 2003. I assume George> that this is a valid time and that it George> will be a leap second; if not choose some other year. [... long calculation ...] George> 2004 January 1st 00:01:00 I would argue that adding one minute might be interpreted either * as an absolute minute (add 60 seconds) * or as the duration of the next calendar minute (which happens to be 60 seconds, too). (both resulting in 00:00:59) In any case, it is merely a matter of interpreting the amount in terms of seconds, and then let the translation inside of calendartime do its work for you. -Peter
Peter Thiemann wrote:
George> OK, what TimeExts does, I hope, is add the appropriate amount of the appropriate George> time unit (whatever it is) directly, then rely on the CalendarTime conversions to George> resolve any overflows. This probably isn't very clear, George> so I'll give some examples of what I think ought to George> happen.
I see. You propose to always add the duration of the current entity. IE, a month rooted in January has 31 days, and a year rooted in a leap year has 366 days. How do you define subtraction, given that your addition is not monotonic and that you (probably) want addition and subtraction be inverses?
I would drop the requirement that addition and subtraction be inverse, and use exactly the same procedure only with changes of sign. So first adjust the date, then roll.
Actually, you could equally well argue that you should always take the duration of the next following entity (in seconds, but I won't go into that detail). While this means that (in a non-leap year) January 1 + 1 month = January 29 it preserves monotonicity: January 31 + 1 month = February 28 so that you could define subtraction (although at some expense).
[snip] Well I don't see much point in arguing this at length, since this is one case where it doesn't really matter what we do so long as we do something. HOWEVER I will make some brief points and then leave it to other Haskellers to argue about. Here are some specific objections. (1) Peter's notion of addition is odd. I can't believe anyone but Peter would say that the date 1 month from 1st January is 29th January in a non-leap year, or 30th January in a leap year. (2) Peter's notion of subtraction is worse. True, it's inverse to addition, but that's all it's good for. For example, if you ask "What happens if you subtract 1 month from 1st February?", then Peter's method gives you "4th January in a normal year, or 3rd January in a leap year". I can't believe if you were to ask someone on the street "What date is 1 month before 1st February?" they would give you that answer. (3) Both are fundamentally asymmetric. What happens for example when you add (-1) months? Do you subtract the length of the previous month? This is nice and symmetrical. Or do you subtract the length of this month? This is not symmetrical, but means that it is the same as subtracting 1 month. However there's an ever better objection which has just occurred to me. Peter's notion of subtraction is UNDEFINED. For, what is 29th January MINUS 1 month? As he says, in his system. January 1 + 1 month = January 29 but of course it is also true that December 29 + 1 month = January 29. Even worse, December 30 + 1 month = January 30th, so you don't have monotonicity either. So while I started typing this thinking it was a straight choice between Peter's monotonicity/invertibility and the fact that my system corresponds better to natural usage, Peter doesn't even have monotonicity or invertibility. So I think my method wins. Nyaaa.
George> So while I started typing this thinking it was a straight George> choice between Peter's monotonicity/invertibility and the George> fact that my system corresponds better to natural usage, George> Peter doesn't even have monotonicity or invertibility. Yes, I also realized that after I left my office. Sorry for the confusion. ... Now, isn't that a good argument for just *defining* the length of a year and a month in terms of seconds and then go with it. It naturally gives you all nice properties and you cannot argue if and when you want to overflow or underflow or whatever? -Peter
On 11 Feb 2003, at 18:23, George Russell wrote:
Add 1 month to 1st February 2003. This produces 1st March 2003. (with no overflow.)
Here, you add 28 days, which is the number of days in (this) February. Fair enough.
Add 1 month to 31st January 2003. Then we get 31st February 2003. This clearly requires an overflow; we note that February 2003 has 28 days, and so roll over to 3rd March 2003.
Here, you add 31 days, which is the number of days in January. Also fair enough.
Note that in this case "Add 1 month" is not a monotonic operation.
Add 1 minute to 23:59:60 31st December 2003. I assume that this is a valid time and that it will be a leap second; if not choose some other year.
This is complicated since we have multiple overflows. First stage you get the invalid time
23:60:60 31st December 2003.
But **HERE**, you add 60 seconds. Why? If you want to add "1 minute" to 23:59:60 31st December 2003, and assuming still that it is a leap minute, then to be consistent with the rule for months, I think you ought to add **61** seconds---the number of seconds in *this* minute. If the problem had been to add "60 seconds", I would agree, but if the problem is to add "1 minute", I think there's a flaw here. /| . . . (_|/ o n a t h a n /| (_/
participants (3)
-
George Russell -
Jonathan Coxhead -
Peter Thiemann