Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:85798 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 19634 invoked from network); 14 Apr 2015 06:39:09 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 14 Apr 2015 06:39:09 -0000 Authentication-Results: pb1.pair.com smtp.mail=peter.e.lind@gmail.com; spf=pass; sender-id=pass Authentication-Results: pb1.pair.com header.from=peter.e.lind@gmail.com; sender-id=pass Received-SPF: pass (pb1.pair.com: domain gmail.com designates 209.85.215.48 as permitted sender) X-PHP-List-Original-Sender: peter.e.lind@gmail.com X-Host-Fingerprint: 209.85.215.48 mail-la0-f48.google.com Received: from [209.85.215.48] ([209.85.215.48:35202] helo=mail-la0-f48.google.com) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id F0/B1-08334-B06BC255 for ; Tue, 14 Apr 2015 02:39:07 -0400 Received: by labbd9 with SMTP id bd9so347035lab.2 for ; Mon, 13 Apr 2015 23:39:04 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:in-reply-to:references:from:date:message-id:subject:to :cc:content-type; bh=Vl3sLi8RYf/Xsz7kBzcTxRvrXMRU/RIodJsTlTNBxT0=; b=B6sWDOmM2dsJdtra+7aeRbt7xUFv9LzgYI8jGWOIp+kDhYRQSRVhVqEssLTXKxzL2i 7geC3iw5Y1QOfxaSqIwOuge47Vi9NTXnb/dDMcRcfL8orsv9GPNNM/Cg5XseiwnGW3Ec HbWpLDzI2zjua7PB9rGEwy706Gr2jqdx8So+o5c/Jx9legiUnGRrZTCxvbbhE8mLg586 pjy7/1gA13zCcJWF/pGQQ/1mn72sGPuhAegazpS6Sra+/3riIpwjMONqroPlFvUF2ajc nOLU7TJZgTc1+rUW7QmnvbwSGTMyrBEdzntn8TwwMonNhwOTvtaLAIU6qpX6b586x+2T kn9Q== X-Received: by 10.112.146.97 with SMTP id tb1mr6268823lbb.12.1428993544220; Mon, 13 Apr 2015 23:39:04 -0700 (PDT) MIME-Version: 1.0 Received: by 10.112.104.35 with HTTP; Mon, 13 Apr 2015 23:38:44 -0700 (PDT) In-Reply-To: References: Date: Tue, 14 Apr 2015 08:38:44 +0200 Message-ID: To: Derick Rethans Cc: PHP internals Content-Type: multipart/alternative; boundary=047d7b3a85a096f47c0513a97c32 Subject: Re: [PHP-DEV] DateInterval bug From: peter.e.lind@gmail.com (Peter Lind) --047d7b3a85a096f47c0513a97c32 Content-Type: text/plain; charset=UTF-8 On 13 April 2015 at 22:20, Derick Rethans 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 -- WWW: plphp.dk / plind.dk CV: careers.stackoverflow.com/peterlind LinkedIn: plind Twitter: kafe15 --047d7b3a85a096f47c0513a97c32--