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");