On 13 April 2015 at 22:20, Derick Rethans <der...@php.net> wrote: > On Sun, 12 Apr 2015, Peter Lind wrote: > > > Hi, > > > > I wanted to get into PHP code development so I grabbed a random bug from > > bugs.php.net. Which turned out to be > https://bugs.php.net/bug.php?id=69378 > > > > The problem the bug report describes is that creating a diff between two > > dates and then subtracting the diff from the later date does not give you > > the former date. Or, as the bug report state, this should hold: > > > > B - (B - A) == A > > > > But it doesn't, because of the way DateInterval and DateTime interact. A > > DateInterval is broken up into years, months, days, hours, minutes and > > seconds - which can be added or subtracted from a date. However, months > are > > not fit size, so the order in which things are added or subtracted > matters. > > In the bug report, the problem arises because months are subtracted > before > > days - and there's a huge difference between subtracting 17 days from 2. > > April and from 2. March. > > > > In itself, this isn't a big problem - but apparently this behaviour is > how > > the system is supposed to work. In the tests for the date extension, I > > found this test for DateTime::add > > > > echo "test_years_positive__6_shy_1_day: "; > > examine_diff('2007-02-06', '2000-02-07', 'P+6Y11M30DT0H0M0S', 2556); > > > > echo "test_years_negative__6_shy_1_day: "; > > examine_diff('2000-02-07', '2007-02-06', 'P-6Y11M28DT0H0M0S', 2556); > > > > The third argument in the examine_diff calls is used in the constructor > > call to DateInterval. The difference is whether the interval will be > > positive or negative. Note the difference of two days - if you add a > > positive interval, then 7 years minus 1 day is 6 years, 11 months and 30 > > days. If you add a negative interval, then 7 years minus 1 day is 6 > years, > > 11 months and 28 days. > > > > Is there a good explanation for this behaviour (which applies both to > > DateTime::add and DateTime::sub)? I've tried searching the internals list > > but couldn't see any discussion of it. It seems like a bug that never got > > fixed to the point where there are tests to make sure things are still > > calculated wrong. > > Why is it a bug? With DateTime math, reversing an operation isn't > necessarily going to work... > > Math that isn't consistent is problematic, in my book. Or, to put it another way: if someone told me, that there is 6 years, 11 months and 30 days between 7th Feb 2000 and 6th Feb 2007, I would agree. If the same person then told me that the interval *is also* 6 years, 11 months and 28 days *and that both intervals are correct* - I would question the sanity of that person. I would go so far as to say: don't ever manage my calendar.
The bug as I see it is that two classes/behaviours have been packed into one - there should be DateIntervalRepresentation and DateInterval. The first shows you how many years, months, days, etc there are between two dates. The second is the actual interval between two dates. The first is context dependent - it needs anchoring in at least one date. The second is context independent. Either that or do away with math you can't rely on. I think what we should aim for in programming languages is the opposite of "isn't necessarily going to work..." Regards Peter -- <hype> WWW: plphp.dk / plind.dk CV: careers.stackoverflow.com/peterlind LinkedIn: plind Twitter: kafe15 </hype>