You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@groovy.apache.org by "paulk-asert (via GitHub)" <gi...@apache.org> on 2026/07/02 04:33:54 UTC

[PR] GROOVY-12124: Modernize the TimeCategory date/time DSL: add a java.ti… [groovy]

paulk-asert opened a new pull request, #2653:
URL: https://github.com/apache/groovy/pull/2653

   …me flavor and a dequirked java.util.Date flavor


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscribe@groovy.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] GROOVY-12124: Modernize the TimeCategory date/time DSL: add a java.ti… [groovy]

Posted by "Copilot (via GitHub)" <gi...@apache.org>.
Copilot commented on code in PR #2653:
URL: https://github.com/apache/groovy/pull/2653#discussion_r3510877746


##########
subprojects/groovy-dateutil/src/main/java/org/apache/groovy/dateutil/BaseDuration.java:
##########
@@ -0,0 +1,187 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package org.apache.groovy.dateutil;
+
+import java.time.temporal.ChronoUnit;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.List;
+
+/**
+ * Base class for date and time durations (dequirked, {@code java.util.Date}-flavored).
+ * <p>
+ * This is the B1 prototype: the same value-class model as the legacy
+ * {@code groovy.time.BaseDuration}, but with the historical quirks removed:
+ * <ul>
+ *   <li><b>ago / from.now no longer zero the time-of-day</b> for date-based durations —
+ *       the behavior is now uniform across all durations (time is preserved), so a single
+ *       implementation lives here rather than divergent overrides per subclass.</li>
+ *   <li><b>{@link #toMilliseconds()} is deterministic</b> — datum-dependent amounts (years,
+ *       months) use {@link ChronoUnit}'s estimated durations rather than resolving against
+ *       {@code new Date()} ("now"), so the result no longer depends on when it is called.</li>
+ * </ul>
+ *
+ * @see Duration
+ */
+public abstract class BaseDuration implements Comparable<BaseDuration> {
+    /** Estimated milliseconds in a year (ChronoUnit.YEARS = 365.2425 days). */
+    static final long MILLIS_PER_YEAR = ChronoUnit.YEARS.getDuration().toMillis();
+    /** Estimated milliseconds in a month (ChronoUnit.MONTHS = 30.436875 days). */
+    static final long MILLIS_PER_MONTH = ChronoUnit.MONTHS.getDuration().toMillis();
+
+    protected final int years;
+    protected final int months;
+    protected final int days;
+    protected final int hours;
+    protected final int minutes;
+    protected final int seconds;
+    protected final int millis;
+
+    protected BaseDuration(final int years, final int months, final int days, final int hours, final int minutes, final int seconds, final int millis) {
+        this.years = years;
+        this.months = months;
+        this.days = days;
+        this.hours = hours;
+        this.minutes = minutes;
+        this.seconds = seconds;
+        this.millis = millis;
+    }
+
+    protected BaseDuration(final int days, final int hours, final int minutes, final int seconds, final int millis) {
+        this(0, 0, days, hours, minutes, seconds, millis);
+    }
+
+    public int getYears()   { return this.years; }
+    public int getMonths()  { return this.months; }
+    public int getDays()    { return this.days; }
+    public int getHours()   { return this.hours; }
+    public int getMinutes() { return this.minutes; }
+    public int getSeconds() { return this.seconds; }
+    public int getMillis()  { return this.millis; }
+
+    /**
+     * Adds this duration to the supplied date.
+     */
+    public Date plus(final Date date) {
+        final Calendar cal = Calendar.getInstance();
+        cal.setTime(date);
+        cal.add(Calendar.YEAR, this.years);
+        cal.add(Calendar.MONTH, this.months);
+        cal.add(Calendar.DAY_OF_YEAR, this.days);
+        cal.add(Calendar.HOUR_OF_DAY, this.hours);
+        cal.add(Calendar.MINUTE, this.minutes);
+        cal.add(Calendar.SECOND, this.seconds);
+        cal.add(Calendar.MILLISECOND, this.millis);
+        return cal.getTime();
+    }
+
+    /**
+     * Converts this duration to milliseconds.
+     * <p>
+     * DEQUIRKED (B): deterministic. Years and months use {@link ChronoUnit} estimates
+     * (a year is exactly 12 estimated months, so {@code 1.year == 12.months}); days and
+     * below are exact assuming 24-hour days. The result never depends on the current date.
+     */
+    public long toMilliseconds() {
+        return years * MILLIS_PER_YEAR
+                + months * MILLIS_PER_MONTH
+                + days * 86_400_000L
+                + hours * 3_600_000L
+                + minutes * 60_000L
+                + seconds * 1_000L
+                + millis;
+    }
+
+    /**
+     * The date this duration ago.
+     * <p>
+     * DEQUIRKED (A): the time-of-day is preserved (no flooring to midnight),
+     * uniformly for all duration kinds.
+     */
+    public Date getAgo() {
+        final Calendar cal = Calendar.getInstance();
+        cal.add(Calendar.YEAR, -this.years);
+        cal.add(Calendar.MONTH, -this.months);
+        cal.add(Calendar.DAY_OF_YEAR, -this.days);
+        cal.add(Calendar.HOUR_OF_DAY, -this.hours);
+        cal.add(Calendar.MINUTE, -this.minutes);
+        cal.add(Calendar.SECOND, -this.seconds);
+        cal.add(Calendar.MILLISECOND, -this.millis);
+        return cal.getTime();
+    }
+
+    /**
+     * Helper for computing dates relative to the current time.
+     * DEQUIRKED (A): time-of-day preserved.
+     */
+    public From getFrom() {
+        return new From() {
+            @Override
+            public Date getNow() {
+                final Calendar cal = Calendar.getInstance();
+                cal.add(Calendar.YEAR, BaseDuration.this.years);
+                cal.add(Calendar.MONTH, BaseDuration.this.months);
+                cal.add(Calendar.DAY_OF_YEAR, BaseDuration.this.days);
+                cal.add(Calendar.HOUR_OF_DAY, BaseDuration.this.hours);
+                cal.add(Calendar.MINUTE, BaseDuration.this.minutes);
+                cal.add(Calendar.SECOND, BaseDuration.this.seconds);
+                cal.add(Calendar.MILLISECOND, BaseDuration.this.millis);
+                return cal.getTime();
+            }
+        };
+    }
+
+    @Override
+    public int compareTo(BaseDuration other) {
+        return Long.signum(toMilliseconds() - other.toMilliseconds());
+    }

Review Comment:
   `compareTo` uses subtraction (`toMilliseconds() - other.toMilliseconds()`), which can overflow and return the wrong sign for large values, breaking the `Comparable` contract (inconsistent ordering in sorted collections). Prefer `Long.compare` to avoid overflow in the comparison step.



##########
subprojects/groovy-dateutil/src/test/groovy/org/apache/groovy/dateutil/TimeCategoryTest.groovy:
##########
@@ -0,0 +1,282 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package org.apache.groovy.dateutil
+
+import org.junit.jupiter.api.Test
+
+import static java.util.Calendar.DAY_OF_YEAR
+import static java.util.Calendar.MONTH
+import static org.junit.jupiter.api.Assertions.assertTrue
+
+/**
+ * Tests the {@link org.apache.groovy.dateutil.TimeCategory} class, the dequirked
+ * {@code java.util.Date}-flavored parallel to the legacy {@code groovy.time.TimeCategory}.
+ * The arithmetic assertions are ported verbatim from the legacy suite; the final section
+ * exercises the two behaviors that were intentionally changed ("dequirked").
+ */
+class TimeCategoryTest {
+
+    @Test
+    void testDurationArithmeticOnMilliseconds() {
+        use(TimeCategory) {
+            def midnight = new Date(100, 0, 1, 0, 0, 0)
+            def oneSecondPastMidnight = new Date(100, 0, 1, 0, 0, 1)
+            def twoSecondsPastMidnight = new Date(100, 0, 1, 0, 0, 2)
+
+            assert (midnight + 1000.millisecond) == oneSecondPastMidnight
+            assert (midnight + 2000.milliseconds) == twoSecondsPastMidnight
+            assert (twoSecondsPastMidnight - 1000.millisecond) == oneSecondPastMidnight
+            assert (twoSecondsPastMidnight - 2000.milliseconds) == midnight
+        }
+    }
+
+    @Test
+    void testDurationArithmeticOnSeconds() {
+        use(TimeCategory) {
+            def midnight = new Date(100, 0, 1, 0, 0, 0)
+            def oneSecondPastMidnight = new Date(100, 0, 1, 0, 0, 1)
+            def twoSecondsPastMidnight = new Date(100, 0, 1, 0, 0, 2)
+
+            assert (midnight + 1.second) == oneSecondPastMidnight
+            assert (midnight + 2.seconds) == twoSecondsPastMidnight
+            assert (twoSecondsPastMidnight - 1.second) == oneSecondPastMidnight
+            assert (twoSecondsPastMidnight - 2.seconds) == midnight
+        }
+    }
+
+    @Test
+    void testDurationArithmeticOnMinutes() {
+        use(TimeCategory) {
+            def midnight = new Date(100, 0, 1, 0, 0, 0)
+            def oneMinutePastMidnight = new Date(100, 0, 1, 0, 1, 0)
+            def twoMinutesPastMidnight = new Date(100, 0, 1, 0, 2, 0)
+
+            assert (midnight + 1.minute) == oneMinutePastMidnight
+            assert (midnight + 2.minutes) == twoMinutesPastMidnight
+            assert (twoMinutesPastMidnight - 60.seconds) == oneMinutePastMidnight
+            assert (twoMinutesPastMidnight - 1.minute) == oneMinutePastMidnight
+            assert (twoMinutesPastMidnight - 120.seconds) == midnight
+            assert (twoMinutesPastMidnight - 2.minutes) == midnight
+        }
+    }
+
+    @Test
+    void testDurationArithmeticOnHours() {
+        use(TimeCategory) {
+            def midnight = new Date(100, 0, 1, 0, 0, 0)
+            def oneAM = new Date(100, 0, 1, 1, 0, 0)
+            def twoAM = new Date(100, 0, 1, 2, 0, 0)
+
+            assert (midnight + 1.hour) == oneAM
+            assert (midnight + 2.hours) == twoAM
+            assert (twoAM - 3600.seconds) == oneAM
+            assert (twoAM - 1.hour) == oneAM
+            assert (twoAM - 7200.seconds) == midnight
+            assert (twoAM - 2.hours) == midnight
+        }
+    }
+
+    @Test
+    void testDurationArithmeticOnDays() {
+        use(TimeCategory) {
+            def januaryFirst = new Date(100, 0, 1, 0, 0, 0)
+            def januarySecond = new Date(100, 0, 2, 0, 0, 0)
+            def januaryThird = new Date(100, 0, 3, 0, 0, 0)
+
+            assert (januaryFirst + 1.day) == januarySecond
+            assert (januaryFirst + 2.days) == januaryThird
+            assert (januaryThird - 1.day) == januarySecond
+            assert (januaryThird - 2.days) == januaryFirst
+        }
+    }
+
+    @Test
+    void testDurationArithmeticOnWeeks() {
+        use(TimeCategory) {
+            def firstWeek = new Date(100, 0, 1, 0, 0, 0)
+            def secondWeek = new Date(100, 0, 8, 0, 0, 0)
+            def thirdWeek = new Date(100, 0, 15, 0, 0, 0)
+
+            assert (firstWeek + 1.week) == secondWeek
+            assert (firstWeek + 2.weeks) == thirdWeek
+            assert (thirdWeek - 1.week) == secondWeek
+            assert (thirdWeek - 2.weeks) == firstWeek
+        }
+    }
+
+    @Test
+    void testDurationArithmeticOnMonths() {
+        use(TimeCategory) {
+            def january = new Date(100, 0, 1, 0, 0, 0)
+            def february = new Date(100, 1, 1, 0, 0, 0)
+            def march = new Date(100, 2, 1, 0, 0, 0)
+
+            assert (january + 1.month) == february
+            assert (january + 2.months) == march
+            assert (march - 1.month) == february
+            assert (march - 2.months) == january
+        }
+    }
+
+    @Test
+    void testDurationArithmeticOnYears() {
+        use(TimeCategory) {
+            def firstYear = new Date(100, 0, 1, 0, 0, 0)
+            def secondYear = new Date(101, 0, 1, 0, 0, 0)
+            def thirdYear = new Date(102, 0, 1, 0, 0, 0)
+
+            assert (firstYear + 1.year) == secondYear
+            assert (firstYear + 2.years) == thirdYear
+            assert (thirdYear - 1.year) == secondYear
+            assert (thirdYear - 2.years) == firstYear
+        }
+    }
+
+    @Test
+    void testDateSubtractionOnSeconds() {
+        use(TimeCategory) {
+            def current = new Date(100, 0, 1, 0, 0, 0)
+            def oneSecondLater = new Date(100, 0, 1, 0, 0, 1)
+            def twoSecondsLater = new Date(100, 0, 1, 0, 0, 2)
+
+            assert (oneSecondLater - current).seconds == 1
+            assert (twoSecondsLater - current).seconds == 2
+        }
+    }
+
+    @Test
+    void testDateSubtractionOnMinutes() {
+        use(TimeCategory) {
+            def current = new Date(100, 0, 1, 0, 0, 0)
+            assert (new Date(100, 0, 1, 0, 1, 0) - current).minutes == 1
+            assert (new Date(100, 0, 1, 0, 2, 0) - current).minutes == 2
+        }
+    }
+
+    @Test
+    void testDateSubtractionOnHours() {
+        use(TimeCategory) {
+            def current = new Date(100, 0, 1, 0, 0, 0)
+            assert (new Date(100, 0, 1, 1, 0, 0) - current).hours == 1
+            assert (new Date(100, 0, 1, 2, 0, 0) - current).hours == 2
+        }
+    }
+
+    @Test
+    void testDateSubtractionOnDays() {
+        use(TimeCategory) {
+            def current = new Date(100, 0, 1, 0, 0, 0)
+            assert (new Date(100, 0, 2, 0, 0, 0) - current).days == 1
+            assert (new Date(100, 0, 3, 0, 0, 0) - current).days == 2
+        }
+    }
+
+    @Test
+    void testDateSubtraction_NoYearsOrMonths() {
+        use(TimeCategory) {
+            def result = new Date(102, 0, 1, 0, 0, 0) - new Date(100, 0, 1, 0, 0, 0)
+            // date subtraction does not populate months and years
+            assert result.years == 0
+            assert result.months == 0
+        }
+    }
+
+    @Test
+    void testToStringForNegativeValues() {
+        use(TimeCategory) {
+            def t1 = Calendar.instance.time
+            def t2 = t1 - 4.seconds + 2.milliseconds
+            def t3 = t1 + 4.seconds + 2.milliseconds
+            def t4 = t1 - 4.seconds - 2.milliseconds
+            def t5 = t1 + 4.seconds - 2.milliseconds
+            def t6 = t1 - 2.milliseconds
+            def t7 = t1 + 2.milliseconds
+            assert (t1 - t2).toString() == '3.998 seconds'
+            assert (t1 - t3).toString() == '-4.002 seconds'
+            assert (t1 - t4).toString() == '4.002 seconds'
+            assert (t1 - t5).toString() == '-3.998 seconds'
+            assert (t1 - t6).toString() == '0.002 seconds'
+            assert (t1 - t7).toString() == '-0.002 seconds'
+        }
+    }
+
+    @Test
+    void testToStringForOverflow() {
+        use(TimeCategory) {
+            def t = 800.milliseconds + 300.milliseconds
+            assert t.toString() == '1.100 seconds'
+        }
+    }
+
+    @Test
+    void testZeroDurationFromNowIsNow() {
+        use(TimeCategory) {
+            // Replaces the legacy testDateEquality, whose reproducibility relied on from.now
+            // flooring to midnight. Dequirked, a zero-length duration from now is (approximately)
+            // now, with the time-of-day preserved.
+            def reference = System.currentTimeMillis()
+            Date result = 0.days.from.now
+            assert Math.abs(result.time - reference) < 2000
+        }

Review Comment:
   This assertion can be flaky under heavy load because it assumes the `.from.now` call happens within 2 seconds of capturing `reference`. Measuring `before`/`after` around the call makes the test robust regardless of scheduling delays.



##########
subprojects/groovy-dateutil/src/test/groovy/org/apache/groovy/dateutil/DurationTest.groovy:
##########
@@ -0,0 +1,171 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package org.apache.groovy.dateutil
+
+import org.junit.jupiter.api.Test
+
+import java.time.temporal.ChronoUnit
+
+import static java.util.Calendar.DAY_OF_YEAR
+import static java.util.Calendar.MONTH
+import static java.util.Calendar.WEEK_OF_YEAR
+import static org.junit.jupiter.api.Assertions.assertEquals
+import static org.junit.jupiter.api.Assertions.assertNotNull
+import static org.junit.jupiter.api.Assertions.assertTrue
+
+/**
+ * Tests for the dequirked {@code org.apache.groovy.dateutil} Duration hierarchy.
+ */
+class DurationTest {
+
+    @Test
+    void testFixedDurationArithmetic() {
+        use(TimeCategory) {
+            def oneDay = 2.days - 1.day
+            assert oneDay.toMilliseconds() == (24 * 60 * 60 * 1000)
+
+            oneDay = 2.days - 1.day + 24.hours - 1440.minutes
+            assert oneDay.toMilliseconds() == (24 * 60 * 60 * 1000)
+        }
+    }
+
+    @Test
+    void testDurationToString() {
+        use(TimeCategory) {
+            assert (0.years).toString() == "0"
+            assert (3.years + 8.months + 4.days + 2.hours + 5.minutes + 12.milliseconds).toString() ==
+                    "3 years, 8 months, 4 days, 2 hours, 5 minutes, 0.012 seconds"
+            assert (4.days + 2.hours + 5.minutes + 12.milliseconds).toString() == "4 days, 2 hours, 5 minutes, 0.012 seconds"
+            assert (4.days + 2.hours + 5.minutes).toString() == "4 days, 2 hours, 5 minutes"
+            assert (5.seconds).toString() == "5.000 seconds"
+            assert ((-12).milliseconds).toString() == "-0.012 seconds"
+            assert (5.seconds + 12.milliseconds).toString() == "5.012 seconds"
+            assert (5.seconds + 1012.milliseconds).toString() == "6.012 seconds"
+        }
+    }
+
+    @Test
+    void testDurationComparison() {
+        use(TimeCategory) {
+            assert 1.week < 2.weeks
+            assert 3.weeks <= 4.weeks
+            assert 10.seconds == 10.seconds
+            assert 4.months >= 1.month
+            assert 10.days > 2.days
+            assert 3.months > 2.months
+            assert 1.second < 1.year
+            assert 1.day > 1000.seconds
+            assert 10.weeks < 10.years
+        }
+    }
+
+    @Test
+    void testConstructor() {
+        def duration = new Duration(1, 2, 3, 4, 5)
+        assertEquals(1, duration.days)
+        assertEquals(2, duration.hours)
+        assertEquals(3, duration.minutes)
+        assertEquals(4, duration.seconds)
+        assertEquals(5, duration.millis)
+    }
+
+    @Test
+    void testToMilliseconds() {
+        assertEquals(24 * 60 * 60 * 1000L, new Duration(1, 0, 0, 0, 0).toMilliseconds())
+        def d = new Duration(1, 2, 3, 4, 5)
+        assertEquals(((((1L * 24 + 2) * 60 + 3) * 60 + 4) * 1000) + 5, d.toMilliseconds())
+    }
+
+    @Test
+    void testDatumDependentToMillisecondsIsDeterministic() { // DEQUIRK B
+        // years/months use fixed ChronoUnit estimates; no dependence on the current date
+        assertEquals(ChronoUnit.YEARS.duration.toMillis(), new DatumDependentDuration(1, 0, 0, 0, 0, 0, 0).toMilliseconds())
+        assertEquals(ChronoUnit.MONTHS.duration.toMillis(), new DatumDependentDuration(0, 1, 0, 0, 0, 0, 0).toMilliseconds())
+        // a year is exactly twelve estimated months
+        assertEquals(new DatumDependentDuration(1, 0, 0, 0, 0, 0, 0).toMilliseconds(),
+                new DatumDependentDuration(0, 12, 0, 0, 0, 0, 0).toMilliseconds())
+    }
+
+    @Test
+    void testPlusDuration() {
+        def result = new Duration(1, 2, 3, 4, 5).plus(new Duration(1, 1, 1, 1, 1))
+        assertEquals(2, result.days); assertEquals(3, result.hours); assertEquals(4, result.minutes)
+        assertEquals(5, result.seconds); assertEquals(6, result.millis)
+    }
+
+    @Test
+    void testPlusDatumDependentDuration() {
+        def result = new Duration(1, 0, 0, 0, 0).plus(new DatumDependentDuration(1, 2, 3, 4, 5, 6, 7))
+        assertNotNull(result)
+        assertEquals(1, result.years); assertEquals(2, result.months)
+    }
+
+    @Test
+    void testMinusDatumDependentDuration() {
+        def result = new Duration(10, 5, 30, 20, 100).minus(new DatumDependentDuration(1, 2, 3, 1, 10, 5, 50))
+        assertEquals(-1, result.years); assertEquals(-2, result.months); assertEquals(7, result.days)
+    }
+
+    @Test
+    void testGetAgoPreservesTimeOfDay() { // DEQUIRK A
+        def ago = new Duration(1, 0, 0, 0, 0).getAgo()
+        def expected = Calendar.instance
+        expected.add(DAY_OF_YEAR, -1)
+        assertTrue Math.abs(expected.timeInMillis - ago.time) < 2000
+    }
+
+    @Test
+    void testGetFromPreservesTimeOfDay() { // DEQUIRK A
+        def now = new Duration(3, 0, 0, 0, 0).from.now
+        def expected = Calendar.instance
+        expected.add(DAY_OF_YEAR, 3)
+        assertTrue Math.abs(expected.timeInMillis - now.time) < 2000
+    }
+
+    @Test
+    void testMinutesAgo() { // See GROOVY-3687 - was already un-quirky for time durations
+        use(TimeCategory) {
+            def now = Calendar.instance
+            def before = 10.minutes.ago
+            now.add(Calendar.MINUTE, -11)
+            assertTrue now.timeInMillis < before.time
+        }
+    }
+
+    @Test
+    void testDatumDependantArithmetic() {

Review Comment:
   Method name uses the misspelling "Dependant" (vs "Dependent" as in `DatumDependentDuration`). Renaming keeps terminology consistent across the codebase and avoids propagating the typo into test reports.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscribe@groovy.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] GROOVY-12124: Modernize the TimeCategory date/time DSL: add a java.ti… [groovy]

Posted by "testlens-app[bot] (via GitHub)" <gi...@apache.org>.
testlens-app[bot] commented on PR #2653:
URL: https://github.com/apache/groovy/pull/2653#issuecomment-4862424785

   ## 🚨 TestLens detected 3 failed tests 🚨
   
   Here is what you can do:
   
   1) Inspect the test failures carefully.
   2) If you are convinced that some of the tests are flaky, you can mute them below.
   3) Finally, trigger a rerun by checking the rerun checkbox.
   
   ### Test Summary
   
   #### [Build and test / lts \(17, macos-latest\)](https://github.com/apache/groovy/actions/runs/28566427606/job/84694670617?pr=2653) > :groovy-dateutil:test
   
   | Test | Runs |
   |---|---|
   | TimeCategoryTest > testDateEquality\(\) | ❌ |
   
   #### [Build and test / lts \(21, ubuntu-latest\)](https://github.com/apache/groovy/actions/runs/28566427606/job/84694670601?pr=2653) > :groovy-dateutil:test
   
   | Test | Runs |
   |---|---|
   | TimeCategoryTest > testDateEquality\(\) | ❌ |
   
   #### [Build and test / lts \(25, ubuntu-latest\)](https://github.com/apache/groovy/actions/runs/28566427606/job/84694670564?pr=2653) > :groovy-dateutil:test
   
   | Test | Runs |
   |---|---|
   | TimeCategoryTest > testDateEquality\(\) | ❌ |
   
   🏷️ Commit: 5cad6b9cc33814156fab3852158253774fa7cfce
   ▶️ Tests:  22132 executed
   🟡 Checks: 6/29 completed
   
   ### Test Failures
   
   <details>
   
   <summary><strong>TimeCategoryTest > testDateEquality()</strong> (:groovy-dateutil:test in <a href="https://github.com/apache/groovy/actions/runs/28566427606/job/84694670617?pr=2653">Build and test / lts (17, macos-latest)</a>)</summary>
   
   ```
   Assertion failed: 
   
   assert dt1 == dt2
          |   |  |
          |   |  Thu Jul 02 05:07:46 UTC 2026
          |   false
          Thu Jul 02 05:07:46 UTC 2026
   
   	at org.codehaus.groovy.runtime.InvokerHelper.createAssertError(InvokerHelper.java:400)
   	at org.apache.groovy.dateutil.TimeCategoryTest$_testDateEquality_closure16.doCall(TimeCategoryTest.groovy:233)
   	at org.apache.groovy.dateutil.TimeCategoryTest$_testDateEquality_closure16.doCall(TimeCategoryTest.groovy)
   	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
   	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
   	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
   	at java.base/java.lang.reflect.Method.invoke(Method.java:569)
   	at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:502)
   	at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:298)
   	at org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.invokeMethod(ClosureMetaClass.java:292)
   	at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1108)
   	at groovy.lang.Closure.call(Closure.java:563)
   	at groovy.lang.Closure.call(Closure.java:517)
   	at org.codehaus.groovy.runtime.GroovyCategorySupport$ThreadCategoryInfo.use(GroovyCategorySupport.java:127)
   	at org.codehaus.groovy.runtime.GroovyCategorySupport.use(GroovyCategorySupport.java:265)
   	at org.codehaus.groovy.runtime.DefaultGroovyMethods.use(DefaultGroovyMethods.java:18779)
   	at org.apache.groovy.dateutil.TimeCategoryTest.testDateEquality(TimeCategoryTest.groovy:229)
   ```
   
   </details>
   <details>
   
   <summary><strong>TimeCategoryTest > testDateEquality()</strong> (:groovy-dateutil:test in <a href="https://github.com/apache/groovy/actions/runs/28566427606/job/84694670601?pr=2653">Build and test / lts (21, ubuntu-latest)</a>)</summary>
   
   ```
   Assertion failed: 
   
   assert dt1 == dt2
          |   |  |
          |   |  Thu Jul 02 05:06:48 UTC 2026
          |   false
          Thu Jul 02 05:06:48 UTC 2026
   
   	at org.codehaus.groovy.runtime.InvokerHelper.createAssertError(InvokerHelper.java:400)
   	at org.apache.groovy.dateutil.TimeCategoryTest$_testDateEquality_closure16.doCall(TimeCategoryTest.groovy:233)
   	at org.apache.groovy.dateutil.TimeCategoryTest$_testDateEquality_closure16.doCall(TimeCategoryTest.groovy)
   	at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)
   	at java.base/java.lang.reflect.Method.invoke(Method.java:580)
   	at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:502)
   	at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:298)
   	at org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.invokeMethod(ClosureMetaClass.java:292)
   	at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1108)
   	at groovy.lang.Closure.call(Closure.java:563)
   	at groovy.lang.Closure.call(Closure.java:517)
   	at org.codehaus.groovy.runtime.GroovyCategorySupport$ThreadCategoryInfo.use(GroovyCategorySupport.java:127)
   	at org.codehaus.groovy.runtime.GroovyCategorySupport.use(GroovyCategorySupport.java:265)
   	at org.codehaus.groovy.runtime.DefaultGroovyMethods.use(DefaultGroovyMethods.java:18779)
   	at org.apache.groovy.dateutil.TimeCategoryTest.testDateEquality(TimeCategoryTest.groovy:229)
   ```
   
   </details>
   <details>
   
   <summary><strong>TimeCategoryTest > testDateEquality()</strong> (:groovy-dateutil:test in <a href="https://github.com/apache/groovy/actions/runs/28566427606/job/84694670564?pr=2653">Build and test / lts (25, ubuntu-latest)</a>)</summary>
   
   ```
   Assertion failed: 
   
   assert dt1 == dt2
          |   |  |
          |   |  Thu Jul 02 05:06:46 UTC 2026
          |   false
          Thu Jul 02 05:06:46 UTC 2026
   
   	at org.codehaus.groovy.runtime.InvokerHelper.createAssertError(InvokerHelper.java:400)
   	at org.apache.groovy.dateutil.TimeCategoryTest$_testDateEquality_closure16.doCall(TimeCategoryTest.groovy:233)
   	at org.apache.groovy.dateutil.TimeCategoryTest$_testDateEquality_closure16.doCall(TimeCategoryTest.groovy)
   	at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:104)
   	at java.base/java.lang.reflect.Method.invoke(Method.java:565)
   	at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:502)
   	at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:298)
   	at org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.invokeMethod(ClosureMetaClass.java:292)
   	at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1108)
   	at groovy.lang.Closure.call(Closure.java:563)
   	at groovy.lang.Closure.call(Closure.java:517)
   	at org.codehaus.groovy.runtime.GroovyCategorySupport$ThreadCategoryInfo.use(GroovyCategorySupport.java:127)
   	at org.codehaus.groovy.runtime.GroovyCategorySupport.use(GroovyCategorySupport.java:265)
   	at org.codehaus.groovy.runtime.DefaultGroovyMethods.use(DefaultGroovyMethods.java:18779)
   	at org.apache.groovy.dateutil.TimeCategoryTest.testDateEquality(TimeCategoryTest.groovy:229)
   ```
   
   </details>
   
   ### Muted Tests
   > [!NOTE]
   > Checks are currently running using the configuration below.
   
   Select tests to mute in this pull request:
   
   🔲 TimeCategoryTest > testDateEquality\(\) <!-- uniqueId=[engine:junit-jupiter]/[class:org.apache.groovy.dateutil.TimeCategoryTest]/[method:testDateEquality()] -->
   
   Reuse successful test results:
   
   🔲 ♻️ Only rerun the tests that failed or were muted before
   
   Click the checkbox to trigger a rerun:
   
   🔲 **Rerun jobs**
   
   ---
   _Learn more about TestLens at [testlens.app](https://testlens.app)._
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscribe@groovy.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] GROOVY-12124: Modernize the TimeCategory date/time DSL: add a java.ti… [groovy]

Posted by "codecov-commenter (via GitHub)" <gi...@apache.org>.
codecov-commenter commented on PR #2653:
URL: https://github.com/apache/groovy/pull/2653#issuecomment-4862687799

   ## [Codecov](https://app.codecov.io/gh/apache/groovy/pull/2653?dropdown=coverage&src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache) Report
   :x: Patch coverage is `79.14692%` with `44 lines` in your changes missing coverage. Please review.
   :white_check_mark: Project coverage is 68.5902%. Comparing base ([`449dfeb`](https://app.codecov.io/gh/apache/groovy/commit/449dfebc985c0a019e59eb110c5cefcec3272bf1?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache)) to head ([`68b3cba`](https://app.codecov.io/gh/apache/groovy/commit/68b3cba78197e2b56e1947771f2470924fc0e1b3?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache)).
   :warning: Report is 2 commits behind head on master.
   
   | [Files with missing lines](https://app.codecov.io/gh/apache/groovy/pull/2653?dropdown=coverage&src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache) | Patch % | Lines |
   |---|---|---|
   | [...he/groovy/dateutil/TimeDatumDependentDuration.java](https://app.codecov.io/gh/apache/groovy/pull/2653?src=pr&el=tree&filepath=subprojects%2Fgroovy-dateutil%2Fsrc%2Fmain%2Fjava%2Forg%2Fapache%2Fgroovy%2Fdateutil%2FTimeDatumDependentDuration.java&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache#diff-c3VicHJvamVjdHMvZ3Jvb3Z5LWRhdGV1dGlsL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9ncm9vdnkvZGF0ZXV0aWwvVGltZURhdHVtRGVwZW5kZW50RHVyYXRpb24uamF2YQ==) | 11.1111% | [16 Missing :warning: ](https://app.codecov.io/gh/apache/groovy/pull/2653?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache) |
   | [...apache/groovy/dateutil/DatumDependentDuration.java](https://app.codecov.io/gh/apache/groovy/pull/2653?src=pr&el=tree&filepath=subprojects%2Fgroovy-dateutil%2Fsrc%2Fmain%2Fjava%2Forg%2Fapache%2Fgroovy%2Fdateutil%2FDatumDependentDuration.java&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache#diff-c3VicHJvamVjdHMvZ3Jvb3Z5LWRhdGV1dGlsL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9ncm9vdnkvZGF0ZXV0aWwvRGF0dW1EZXBlbmRlbnREdXJhdGlvbi5qYXZh) | 55.0000% | [9 Missing :warning: ](https://app.codecov.io/gh/apache/groovy/pull/2653?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache) |
   | [.../java/org/apache/groovy/dateutil/TimeDuration.java](https://app.codecov.io/gh/apache/groovy/pull/2653?src=pr&el=tree&filepath=subprojects%2Fgroovy-dateutil%2Fsrc%2Fmain%2Fjava%2Forg%2Fapache%2Fgroovy%2Fdateutil%2FTimeDuration.java&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache#diff-c3VicHJvamVjdHMvZ3Jvb3Z5LWRhdGV1dGlsL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9ncm9vdnkvZGF0ZXV0aWwvVGltZUR1cmF0aW9uLmphdmE=) | 50.0000% | [9 Missing :warning: ](https://app.codecov.io/gh/apache/groovy/pull/2653?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache) |
   | [.../java/org/apache/groovy/datetime/TimeCategory.java](https://app.codecov.io/gh/apache/groovy/pull/2653?src=pr&el=tree&filepath=subprojects%2Fgroovy-datetime%2Fsrc%2Fmain%2Fjava%2Forg%2Fapache%2Fgroovy%2Fdatetime%2FTimeCategory.java&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache#diff-c3VicHJvamVjdHMvZ3Jvb3Z5LWRhdGV0aW1lL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9ncm9vdnkvZGF0ZXRpbWUvVGltZUNhdGVnb3J5LmphdmE=) | 85.7143% | [4 Missing :warning: ](https://app.codecov.io/gh/apache/groovy/pull/2653?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache) |
   | [...main/java/org/apache/groovy/dateutil/Duration.java](https://app.codecov.io/gh/apache/groovy/pull/2653?src=pr&el=tree&filepath=subprojects%2Fgroovy-dateutil%2Fsrc%2Fmain%2Fjava%2Forg%2Fapache%2Fgroovy%2Fdateutil%2FDuration.java&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache#diff-c3VicHJvamVjdHMvZ3Jvb3Z5LWRhdGV1dGlsL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9ncm9vdnkvZGF0ZXV0aWwvRHVyYXRpb24uamF2YQ==) | 80.9524% | [4 Missing :warning: ](https://app.codecov.io/gh/apache/groovy/pull/2653?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache) |
   | [.../java/org/apache/groovy/dateutil/BaseDuration.java](https://app.codecov.io/gh/apache/groovy/pull/2653?src=pr&el=tree&filepath=subprojects%2Fgroovy-dateutil%2Fsrc%2Fmain%2Fjava%2Forg%2Fapache%2Fgroovy%2Fdateutil%2FBaseDuration.java&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache#diff-c3VicHJvamVjdHMvZ3Jvb3Z5LWRhdGV1dGlsL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9ncm9vdnkvZGF0ZXV0aWwvQmFzZUR1cmF0aW9uLmphdmE=) | 98.5294% | [1 Missing :warning: ](https://app.codecov.io/gh/apache/groovy/pull/2653?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache) |
   | [.../java/org/apache/groovy/dateutil/TimeCategory.java](https://app.codecov.io/gh/apache/groovy/pull/2653?src=pr&el=tree&filepath=subprojects%2Fgroovy-dateutil%2Fsrc%2Fmain%2Fjava%2Forg%2Fapache%2Fgroovy%2Fdateutil%2FTimeCategory.java&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache#diff-c3VicHJvamVjdHMvZ3Jvb3Z5LWRhdGV1dGlsL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9ncm9vdnkvZGF0ZXV0aWwvVGltZUNhdGVnb3J5LmphdmE=) | 97.3684% | [1 Missing :warning: ](https://app.codecov.io/gh/apache/groovy/pull/2653?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache) |
   
   <details><summary>Additional details and impacted files</summary>
   
   
   
   [![Impacted file tree graph](https://app.codecov.io/gh/apache/groovy/pull/2653/graphs/tree.svg?width=650&height=150&src=pr&token=1r45138NfQ&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache)](https://app.codecov.io/gh/apache/groovy/pull/2653?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache)
   
   ```diff
   @@                Coverage Diff                 @@
   ##               master      #2653        +/-   ##
   ==================================================
   + Coverage     68.5728%   68.5902%   +0.0174%     
   - Complexity      33803      33884        +81     
   ==================================================
     Files            1524       1531         +7     
     Lines          128128     128339       +211     
     Branches        23289      23298         +9     
   ==================================================
   + Hits            87861      88028       +167     
   - Misses          32468      32510        +42     
   - Partials         7799       7801         +2     
   ```
   
   | [Files with missing lines](https://app.codecov.io/gh/apache/groovy/pull/2653?dropdown=coverage&src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache) | Coverage Δ | |
   |---|---|---|
   | [src/main/java/groovy/time/BaseDuration.java](https://app.codecov.io/gh/apache/groovy/pull/2653?src=pr&el=tree&filepath=src%2Fmain%2Fjava%2Fgroovy%2Ftime%2FBaseDuration.java&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache#diff-c3JjL21haW4vamF2YS9ncm9vdnkvdGltZS9CYXNlRHVyYXRpb24uamF2YQ==) | `100.0000% <ø> (ø)` | |
   | [.../main/java/groovy/time/DatumDependentDuration.java](https://app.codecov.io/gh/apache/groovy/pull/2653?src=pr&el=tree&filepath=src%2Fmain%2Fjava%2Fgroovy%2Ftime%2FDatumDependentDuration.java&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache#diff-c3JjL21haW4vamF2YS9ncm9vdnkvdGltZS9EYXR1bURlcGVuZGVudER1cmF0aW9uLmphdmE=) | `100.0000% <ø> (ø)` | |
   | [src/main/java/groovy/time/Duration.java](https://app.codecov.io/gh/apache/groovy/pull/2653?src=pr&el=tree&filepath=src%2Fmain%2Fjava%2Fgroovy%2Ftime%2FDuration.java&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache#diff-c3JjL21haW4vamF2YS9ncm9vdnkvdGltZS9EdXJhdGlvbi5qYXZh) | `100.0000% <ø> (ø)` | |
   | [src/main/java/groovy/time/TimeCategory.java](https://app.codecov.io/gh/apache/groovy/pull/2653?src=pr&el=tree&filepath=src%2Fmain%2Fjava%2Fgroovy%2Ftime%2FTimeCategory.java&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache#diff-c3JjL21haW4vamF2YS9ncm9vdnkvdGltZS9UaW1lQ2F0ZWdvcnkuamF2YQ==) | `87.7551% <ø> (ø)` | |
   | [...n/java/groovy/time/TimeDatumDependentDuration.java](https://app.codecov.io/gh/apache/groovy/pull/2653?src=pr&el=tree&filepath=src%2Fmain%2Fjava%2Fgroovy%2Ftime%2FTimeDatumDependentDuration.java&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache#diff-c3JjL21haW4vamF2YS9ncm9vdnkvdGltZS9UaW1lRGF0dW1EZXBlbmRlbnREdXJhdGlvbi5qYXZh) | `100.0000% <ø> (ø)` | |
   | [src/main/java/groovy/time/TimeDuration.java](https://app.codecov.io/gh/apache/groovy/pull/2653?src=pr&el=tree&filepath=src%2Fmain%2Fjava%2Fgroovy%2Ftime%2FTimeDuration.java&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache#diff-c3JjL21haW4vamF2YS9ncm9vdnkvdGltZS9UaW1lRHVyYXRpb24uamF2YQ==) | `100.0000% <ø> (ø)` | |
   | [.../java/org/apache/groovy/dateutil/BaseDuration.java](https://app.codecov.io/gh/apache/groovy/pull/2653?src=pr&el=tree&filepath=subprojects%2Fgroovy-dateutil%2Fsrc%2Fmain%2Fjava%2Forg%2Fapache%2Fgroovy%2Fdateutil%2FBaseDuration.java&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache#diff-c3VicHJvamVjdHMvZ3Jvb3Z5LWRhdGV1dGlsL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9ncm9vdnkvZGF0ZXV0aWwvQmFzZUR1cmF0aW9uLmphdmE=) | `98.5294% <98.5294%> (ø)` | |
   | [.../java/org/apache/groovy/dateutil/TimeCategory.java](https://app.codecov.io/gh/apache/groovy/pull/2653?src=pr&el=tree&filepath=subprojects%2Fgroovy-dateutil%2Fsrc%2Fmain%2Fjava%2Forg%2Fapache%2Fgroovy%2Fdateutil%2FTimeCategory.java&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache#diff-c3VicHJvamVjdHMvZ3Jvb3Z5LWRhdGV1dGlsL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9ncm9vdnkvZGF0ZXV0aWwvVGltZUNhdGVnb3J5LmphdmE=) | `97.3684% <97.3684%> (ø)` | |
   | [.../java/org/apache/groovy/datetime/TimeCategory.java](https://app.codecov.io/gh/apache/groovy/pull/2653?src=pr&el=tree&filepath=subprojects%2Fgroovy-datetime%2Fsrc%2Fmain%2Fjava%2Forg%2Fapache%2Fgroovy%2Fdatetime%2FTimeCategory.java&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache#diff-c3VicHJvamVjdHMvZ3Jvb3Z5LWRhdGV0aW1lL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9ncm9vdnkvZGF0ZXRpbWUvVGltZUNhdGVnb3J5LmphdmE=) | `85.7143% <85.7143%> (ø)` | |
   | [...main/java/org/apache/groovy/dateutil/Duration.java](https://app.codecov.io/gh/apache/groovy/pull/2653?src=pr&el=tree&filepath=subprojects%2Fgroovy-dateutil%2Fsrc%2Fmain%2Fjava%2Forg%2Fapache%2Fgroovy%2Fdateutil%2FDuration.java&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache#diff-c3VicHJvamVjdHMvZ3Jvb3Z5LWRhdGV1dGlsL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9ncm9vdnkvZGF0ZXV0aWwvRHVyYXRpb24uamF2YQ==) | `80.9524% <80.9524%> (ø)` | |
   | ... and [3 more](https://app.codecov.io/gh/apache/groovy/pull/2653?src=pr&el=tree-more&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache) | |
   
   ... and [6 files with indirect coverage changes](https://app.codecov.io/gh/apache/groovy/pull/2653/indirect-changes?src=pr&el=tree-more&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache)
   </details>
   <details><summary> :rocket: New features to boost your workflow: </summary>
   
   - :snowflake: [Test Analytics](https://docs.codecov.com/docs/test-analytics): Detect flaky tests, report on failures, and find test suite problems.
   - :package: [JS Bundle Analysis](https://docs.codecov.com/docs/javascript-bundle-analysis): Save yourself from yourself by tracking and limiting bundle sizes in JS merges.
   </details>


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscribe@groovy.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] GROOVY-12124: Modernize the TimeCategory date/time DSL: add a java.ti… [groovy]

Posted by "testlens-app[bot] (via GitHub)" <gi...@apache.org>.
testlens-app[bot] commented on PR #2653:
URL: https://github.com/apache/groovy/pull/2653#issuecomment-4862789824

   ## ✅ All tests passed ✅
   
   🏷️ Commit: 68b3cba78197e2b56e1947771f2470924fc0e1b3
   ▶️ Tests:  102771 executed
   ⚪️ Checks: 31/31 completed
   
   ---
   _Learn more about TestLens at [testlens.app](https://testlens.app)._
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscribe@groovy.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] GROOVY-12124: Modernize the TimeCategory date/time DSL: add a java.ti… [groovy]

Posted by "paulk-asert (via GitHub)" <gi...@apache.org>.
paulk-asert merged PR #2653:
URL: https://github.com/apache/groovy/pull/2653


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscribe@groovy.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] GROOVY-12124: Modernize the TimeCategory date/time DSL: add a java.ti… [groovy]

Posted by "testlens-app[bot] (via GitHub)" <gi...@apache.org>.
testlens-app[bot] commented on PR #2653:
URL: https://github.com/apache/groovy/pull/2653#issuecomment-4862263676

   ## 🚨 TestLens detected 1 failed test 🚨
   
   Here is what you can do:
   
   1) Inspect the test failures carefully.
   2) If you are convinced that some of the tests are flaky, you can mute them below.
   3) Finally, trigger a rerun by checking the rerun checkbox.
   
   ### Test Summary
   
   #### [Build and test / lts \(21, ubuntu-latest\)](https://github.com/apache/groovy/actions/runs/28565636493/job/84692240733?pr=2653) > :groovy-dateutil:test
   
   | Test | Runs |
   |---|---|
   | TimeCategoryTest > testDateEquality\(\) | ❌ |
   
   🏷️ Commit: ca431b58361f782f1dcc9cc1ec4e9ff5d585b723
   ▶️ Tests:  10048 executed
   🟡 Checks: 2/29 completed
   
   ### Test Failures
   
   <details>
   
   <summary><strong>TimeCategoryTest > testDateEquality()</strong> (:groovy-dateutil:test in <a href="https://github.com/apache/groovy/actions/runs/28565636493/job/84692240733?pr=2653">Build and test / lts (21, ubuntu-latest)</a>)</summary>
   
   ```
   Assertion failed: 
   
   assert dt1 == dt2
          |   |  |
          |   |  Thu Jul 02 04:41:31 UTC 2026
          |   false
          Thu Jul 02 04:41:31 UTC 2026
   
   	at org.codehaus.groovy.runtime.InvokerHelper.createAssertError(InvokerHelper.java:400)
   	at org.apache.groovy.dateutil.TimeCategoryTest$_testDateEquality_closure16.doCall(TimeCategoryTest.groovy:233)
   	at org.apache.groovy.dateutil.TimeCategoryTest$_testDateEquality_closure16.doCall(TimeCategoryTest.groovy)
   	at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)
   	at java.base/java.lang.reflect.Method.invoke(Method.java:580)
   	at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:502)
   	at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:298)
   	at org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.invokeMethod(ClosureMetaClass.java:292)
   	at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1108)
   	at groovy.lang.Closure.call(Closure.java:563)
   	at groovy.lang.Closure.call(Closure.java:517)
   	at org.codehaus.groovy.runtime.GroovyCategorySupport$ThreadCategoryInfo.use(GroovyCategorySupport.java:127)
   	at org.codehaus.groovy.runtime.GroovyCategorySupport.use(GroovyCategorySupport.java:265)
   	at org.codehaus.groovy.runtime.DefaultGroovyMethods.use(DefaultGroovyMethods.java:18779)
   	at org.apache.groovy.dateutil.TimeCategoryTest.testDateEquality(TimeCategoryTest.groovy:229)
   ```
   
   </details>
   
   ### Muted Tests
   > [!NOTE]
   > Checks are currently running using the configuration below.
   
   Select tests to mute in this pull request:
   
   🔲 TimeCategoryTest > testDateEquality\(\) <!-- uniqueId=[engine:junit-jupiter]/[class:org.apache.groovy.dateutil.TimeCategoryTest]/[method:testDateEquality()] -->
   
   Reuse successful test results:
   
   🔲 ♻️ Only rerun the tests that failed or were muted before
   
   Click the checkbox to trigger a rerun:
   
   🔲 **Rerun jobs**
   
   ---
   _Learn more about TestLens at [testlens.app](https://testlens.app)._
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscribe@groovy.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] GROOVY-12124: Modernize the TimeCategory date/time DSL: add a java.ti… [groovy]

Posted by "testlens-app[bot] (via GitHub)" <gi...@apache.org>.
testlens-app[bot] commented on PR #2653:
URL: https://github.com/apache/groovy/pull/2653#issuecomment-4863433214

   ## ✅ All tests passed ✅
   
   🏷️ Commit: 32b5dffed9d3b4bd3b4feba3fe84b8ff568daf97
   ▶️ Tests:  102771 executed
   ⚪️ Checks: 31/31 completed
   
   ---
   _Learn more about TestLens at [testlens.app](https://testlens.app)._
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscribe@groovy.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org