[ https://issues.apache.org/jira/browse/GROOVY-8368?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16226038#comment-16226038 ] 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 for dates, following the semantics of a date, which is basically rooted in the way use dates in our language. If you project a date to a real number like a long and any duration as well you would end up with a commutative operation, but you also imply that 1.month means a fixed number of days, and that is not true for for example Oct 1 plus one month and Nov 1 plus one months. One time you add 31, one time 30 days. This means our use in this mini DSL is more near the way we use dates in the common language, but we loose the easy projection on a real number. In other words: it is not comparable and the operation may have very different properties I personally like matrix multiplication as an example. Here we have A*B != B*A in the general case. There are A and B for which we can have an equal here, but in general we can not say this. For real numbers a*b is always b*a. We just lost commutativity here. LetÂ´s do something crazy that mathematicians like to do... define our own binary operator *, where x*y=x+y+y. then 1*2 is suddenly 5, but 2*1 is 4. And we lost commutativity. Or let's define an binary operator +, where x+y=x/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_131 > Reporter: Brian Koehmstedt > Priority: Minor > Attachments: intervalBug.groovy > > > There's what I think to be a date arithmetic bug using TimeCategory intervals and it appears to show itself only the 30th of any given month. I noticed this because our automatic builds fail towards the end of the month due to failing tests and this has been going on for a long time. I decided to 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 shown below. I tested with latest 2.6.0 alpha1 as well as 2.4.10 (what we're 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 the following two expressions should always evaluate to the same value and it appears they don't on the 30th of the month: > {code} > Date now = new Date().clearTime() > // fails on the 30th of the month (at least, for Oct 30 2017) > assert now + 1.month + 1.day == now + 1.day + 1.month > {code} > {code} > // START of intervalBug.groovy > import groovy.time.TimeCategory > Date now = new Date().clearTime() > println "current date = \$now" > use(TimeCategory) { > println "now+1day+1month = \${now + 1.day + 1.month}" > println "now+1month+1day = \${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 OS: 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 = Sun Oct 29 00:00:00 PDT 2017 > now+1day+1month = Thu Nov 30 00:00:00 PST 2017 > now+1month+1day = 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 = Mon Oct 30 00:00:00 PDT 2017 > now+1day+1month = Thu Nov 30 00:00:00 PST 2017 > now+1month+1day = 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: > Tue Oct 31 13:00:00 PDT 2017 > current date = Tue Oct 31 00:00:00 PDT 2017 > now+1day+1month = Fri Dec 01 00:00:00 PST 2017 > now+1month+1day = 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: > Wed Nov 1 13:00:00 PDT 2017 > current date = Wed Nov 01 00:00:00 PDT 2017 > now+1day+1month = Sat Dec 02 00:00:00 PST 2017 > now+1month+1day = Sat Dec 02 00:00:00 PST 2017 > {noformat} -- This message was sent by Atlassian JIRA (v6.4.14#64029)