This is an automated email from the ASF dual-hosted git repository.

ggregory pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-lang.git


The following commit(s) were added to refs/heads/master by this push:
     new a9a0dd8a7 LANG-771 Fix DateUtils.ceiling increment on exact boundary 
(#1609)
a9a0dd8a7 is described below

commit a9a0dd8a72c51b14f0e5ea4bddfbf228685ff977
Author: Indy <[email protected]>
AuthorDate: Mon Feb 23 02:37:04 2026 +0530

    LANG-771 Fix DateUtils.ceiling increment on exact boundary (#1609)
    
    * LANG-771 Fix DateUtils.ceiling increment on exact boundary
    
    * Fix Checkstyle violations for LANG-771
    
    * LANG-771 Add edge case tests for DateUtils.ceiling()
    
    Add tests for:
    - Epoch (0)
    - Negative date (-1)
    - Long.MIN_VALUE and Long.MAX_VALUE handling
    - Minute boundary case
---
 .../org/apache/commons/lang3/time/DateUtils.java     |  4 +++-
 .../org/apache/commons/lang3/time/DateUtilsTest.java | 20 ++++++++++++++++++++
 2 files changed, 23 insertions(+), 1 deletion(-)

diff --git a/src/main/java/org/apache/commons/lang3/time/DateUtils.java 
b/src/main/java/org/apache/commons/lang3/time/DateUtils.java
index f8abf1429..09e0998c8 100644
--- a/src/main/java/org/apache/commons/lang3/time/DateUtils.java
+++ b/src/main/java/org/apache/commons/lang3/time/DateUtils.java
@@ -1115,6 +1115,8 @@ private static Calendar modify(final Calendar val, final 
int field, final Modify
             return val;
         }
 
+        final long originalMillis = val.getTimeInMillis();
+
         // Fix for LANG-59 START
         // see https://issues.apache.org/jira/browse/LANG-59
         //
@@ -1161,7 +1163,7 @@ private static Calendar modify(final Calendar val, final 
int field, final Modify
             for (final int element : aField) {
                 if (element == field) {
                     //This is our field... we stop looping
-                    if (modType == ModifyType.CEILING || modType == 
ModifyType.ROUND && roundUp) {
+                    if (modType == ModifyType.CEILING && originalMillis != 
val.getTimeInMillis() || modType == ModifyType.ROUND && roundUp) {
                         if (field == SEMI_MONTH) {
                             //This is a special case that's hard to generalize
                             //If the date is 1, we round up to 16, otherwise
diff --git a/src/test/java/org/apache/commons/lang3/time/DateUtilsTest.java 
b/src/test/java/org/apache/commons/lang3/time/DateUtilsTest.java
index af4281563..21b1dfdcd 100644
--- a/src/test/java/org/apache/commons/lang3/time/DateUtilsTest.java
+++ b/src/test/java/org/apache/commons/lang3/time/DateUtilsTest.java
@@ -231,6 +231,7 @@ private static Stream<Arguments> 
testToLocalDateTimeTimeZone() {
     private Date date6;
     private Date date7;
     private Date date8;
+    private Date date9;
     private Calendar calAmPm1;
     private Calendar calAmPm2;
     private Calendar calAmPm3;
@@ -284,6 +285,7 @@ public void setUp() throws Exception {
             dateTimeParser.setTimeZone(TIME_ZONE_DEFAULT);
             TimeZone.setDefault(TIME_ZONE_DEFAULT);
         }
+        date9 = dateTimeParser.parse("March 30, 2003 01:10:00.000");
         calAmPm1 = Calendar.getInstance();
         calAmPm1.setTime(dateAmPm1);
         calAmPm2 = Calendar.getInstance();
@@ -531,6 +533,24 @@ void testCeiling() throws Exception {
         assertEquals(dateTimeParser.parse("November 18, 2001 1:24:00.000"),
                 DateUtils.ceiling(date2, Calendar.MINUTE),
                 "ceiling minute-2 failed");
+        // Edge cases (LANG-771)
+        assertEquals(dateTimeParser.parse("March 30, 2003 01:10:00.000"),
+                DateUtils.ceiling(date9, Calendar.MINUTE),
+                "ceiling minute boundary failed");
+        final Date epoch = new Date(0);
+        assertEquals(epoch,
+                DateUtils.ceiling(epoch, Calendar.MINUTE),
+                "ceiling minute epoch failed");
+        final Date negative = new Date(-1);
+        assertEquals(new Date(0),
+                DateUtils.ceiling(negative, Calendar.MINUTE),
+                "ceiling minute negative failed");
+        assertThrows(ArithmeticException.class,
+                () -> DateUtils.ceiling(new Date(Long.MIN_VALUE), 
Calendar.MINUTE),
+                "ceiling minute Long.MIN_VALUE failed");
+        assertThrows(ArithmeticException.class,
+                () -> DateUtils.ceiling(new Date(Long.MAX_VALUE), 
Calendar.MINUTE),
+                "ceiling minute Long.MAX_VALUE failed");
         assertEquals(dateTimeParser.parse("February 12, 2002 12:34:57.000"),
                 DateUtils.ceiling(date1, Calendar.SECOND),
                 "ceiling second-1 failed");

Reply via email to