Return-Path: X-Original-To: archive-asf-public-internal@cust-asf2.ponee.io Delivered-To: archive-asf-public-internal@cust-asf2.ponee.io Received: from cust-asf.ponee.io (cust-asf.ponee.io [163.172.22.183]) by cust-asf2.ponee.io (Postfix) with ESMTP id 94854200D3C for ; Tue, 31 Oct 2017 01:24:10 +0100 (CET) Received: by cust-asf.ponee.io (Postfix) id 93568160BFB; Tue, 31 Oct 2017 00:24:10 +0000 (UTC) Delivered-To: archive-asf-public@cust-asf.ponee.io Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by cust-asf.ponee.io (Postfix) with SMTP id B3587160BF9 for ; Tue, 31 Oct 2017 01:24:09 +0100 (CET) Received: (qmail 42398 invoked by uid 500); 31 Oct 2017 00:24:08 -0000 Mailing-List: contact notifications-help@groovy.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@groovy.apache.org Delivered-To: mailing list notifications@groovy.apache.org Received: (qmail 42389 invoked by uid 99); 31 Oct 2017 00:24:08 -0000 Received: from pnap-us-west-generic-nat.apache.org (HELO spamd1-us-west.apache.org) (209.188.14.142) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 31 Oct 2017 00:24:08 +0000 Received: from localhost (localhost [127.0.0.1]) by spamd1-us-west.apache.org (ASF Mail Server at spamd1-us-west.apache.org) with ESMTP id 29016CE6EF for ; Tue, 31 Oct 2017 00:24:08 +0000 (UTC) X-Virus-Scanned: Debian amavisd-new at spamd1-us-west.apache.org X-Spam-Flag: NO X-Spam-Score: -99.202 X-Spam-Level: X-Spam-Status: No, score=-99.202 tagged_above=-999 required=6.31 tests=[KAM_ASCII_DIVIDERS=0.8, RP_MATCHES_RCVD=-0.001, SPF_PASS=-0.001, USER_IN_WHITELIST=-100] autolearn=disabled Received: from mx1-lw-us.apache.org ([10.40.0.8]) by localhost (spamd1-us-west.apache.org [10.40.0.7]) (amavisd-new, port 10024) with ESMTP id Bfxio9gOb-SW for ; Tue, 31 Oct 2017 00:24:07 +0000 (UTC) Received: from mailrelay1-us-west.apache.org (mailrelay1-us-west.apache.org [209.188.14.139]) by mx1-lw-us.apache.org (ASF Mail Server at mx1-lw-us.apache.org) with ESMTP id 001485FD89 for ; Tue, 31 Oct 2017 00:24:06 +0000 (UTC) Received: from jira-lw-us.apache.org (unknown [207.244.88.139]) by mailrelay1-us-west.apache.org (ASF Mail Server at mailrelay1-us-west.apache.org) with ESMTP id 80E7EE0F67 for ; Tue, 31 Oct 2017 00:24:02 +0000 (UTC) Received: from jira-lw-us.apache.org (localhost [127.0.0.1]) by jira-lw-us.apache.org (ASF Mail Server at jira-lw-us.apache.org) with ESMTP id 7FE9B21304 for ; Tue, 31 Oct 2017 00:24:00 +0000 (UTC) Date: Tue, 31 Oct 2017 00:24:00 +0000 (UTC) From: "Jochen Theodorou (JIRA)" To: notifications@groovy.apache.org Message-ID: In-Reply-To: References: Subject: [jira] [Commented] (GROOVY-8368) date arithmetic bug using TimeCategory intervals MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable X-JIRA-FingerPrint: 30527f35849b9dde25b450d4833f0394 archived-at: Tue, 31 Oct 2017 00:24:10 -0000 [ https://issues.apache.org/jira/browse/GROOVY-8368?page=3Dcom.atlassia= n.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=3D162= 26038#comment-16226038 ]=20 Jochen Theodorou commented on GROOVY-8368: ------------------------------------------ I suggest you read on https://en.wikipedia.org/wiki/Commutative_property Yes, we use the operator + here, but this plus is not the plus operator as = it is defined for real numbers. I higher algebra you always have to define = the operator and + is just a symbol. And for a DSL as here we can redefine = plus of course to fit the domain. The plus operator here is then defined fo= r dates, following the semantics of a date, which is basically rooted in th= e way use dates in our language. If you project a date to a real number lik= e a long and any duration as well you would end up with a commutative opera= tion, but you also imply that 1.month means a fixed number of days, and tha= t is not true for for example Oct 1 plus one month and Nov 1 plus one month= s. One time you add 31, one time 30 days. This means our use in this mini D= SL is more near the way we use dates in the common language, but we loose t= he easy projection on a real number. In other words: it is not comparable a= nd the operation may have very different properties I personally like matrix multiplication as an example. Here we have A*B != =3D B*A in the general case. There are A and B for which we can have an equ= al here, but in general we can not say this. For real numbers a*b is always= b*a. We just lost commutativity here. Let=C2=B4s do something crazy that mathematicians like to do... define our = own binary operator *, where x*y=3Dx+y+y. then 1*2 is suddenly 5, but 2*1 i= s 4. And we lost commutativity. Or let's define an binary operator +, where= x+y=3Dx/y. Then 1+2 is 0.5 and 2+1 is 2. Here we lost commutativity again. > date arithmetic bug using TimeCategory intervals > ------------------------------------------------ > > Key: GROOVY-8368 > URL: https://issues.apache.org/jira/browse/GROOVY-8368 > Project: Groovy > Issue Type: Bug > Affects Versions: 2.6.0-alpha-1 > Environment: Ubuntu 16.04, Groovy 2.6.0-alpha-1, OpenJDK 1.8.0_13= 1 > Reporter: Brian Koehmstedt > Priority: Minor > Attachments: intervalBug.groovy > > > There's what I think to be a date arithmetic bug using TimeCategory inter= vals and it appears to show itself only the 30th of any given month. I not= iced this because our automatic builds fail towards the end of the month du= e to failing tests and this has been going on for a long time. I decided t= o hunt this down today (Oct 30) as the build failed today and I had time to= track it down. I was able to produce a small script to reproduce it, as s= hown below. I tested with latest 2.6.0 alpha1 as well as 2.4.10 (what we'r= e actually using). Both show the bug. > I don't have an opinion on how "1.month" is interpreted in Groovy. That'= s not what this submission is about. The bug I am reporting here is that t= he following two expressions should always evaluate to the same value and i= t appears they don't on the 30th of the month: > {code} > Date now =3D new Date().clearTime() > // fails on the 30th of the month (at least, for Oct 30 2017) > assert now + 1.month + 1.day =3D=3D now + 1.day + 1.month > {code} > {code} > // START of intervalBug.groovy > import groovy.time.TimeCategory > Date now =3D new Date().clearTime() > println "current date =3D $now" > use(TimeCategory) { > println "now+1day+1month =3D ${now + 1.day + 1.month}" > println "now+1month+1day =3D ${now + 1.month + 1.day}" > } > // END of intervalBug.groovy > {code} > {noformat} > # also tested with groovy-2.4.10 with same buggy result > $ groovy -v > Groovy Version: 2.6.0-alpha-1 JVM: 1.8.0_131 Vendor: Oracle Corporation O= S: Linux > # 29th of month is OK: same result produced > $ sudo date -s "29 OCT 2017 13:00:00"; groovy intervalBug.groovy > Sun Oct 29 13:00:00 PDT 2017 > current date =3D Sun Oct 29 00:00:00 PDT 2017 > now+1day+1month =3D Thu Nov 30 00:00:00 PST 2017 > now+1month+1day =3D Thu Nov 30 00:00:00 PST 2017 > # 30th of month is BUGGY: different result produced > $ sudo date -s "30 OCT 2017 13:00:00"; groovy intervalBug.groovy > Mon Oct 30 13:00:00 PDT 2017 > current date =3D Mon Oct 30 00:00:00 PDT 2017 > now+1day+1month =3D Thu Nov 30 00:00:00 PST 2017 > now+1month+1day =3D Fri Dec 01 00:00:00 PST 2017 > # 31st of month is OK > $ sudo date -s "31 OCT 2017 13:00:00"; groovy intervalBug.groovy > [sudo] password for bkoehmstedt:=20 > Tue Oct 31 13:00:00 PDT 2017 > current date =3D Tue Oct 31 00:00:00 PDT 2017 > now+1day+1month =3D Fri Dec 01 00:00:00 PST 2017 > now+1month+1day =3D Fri Dec 01 00:00:00 PST 2017 > # 1st of month is OK > $ sudo date -s "01 NOV 2017 13:00:00"; groovy intervalBug.groovy > [sudo] password for bkoehmstedt:=20 > Wed Nov 1 13:00:00 PDT 2017 > current date =3D Wed Nov 01 00:00:00 PDT 2017 > now+1day+1month =3D Sat Dec 02 00:00:00 PST 2017 > now+1month+1day =3D Sat Dec 02 00:00:00 PST 2017 > {noformat} -- This message was sent by Atlassian JIRA (v6.4.14#64029)