Alwaysgaurav1 opened a new pull request, #1780:
URL: https://github.com/apache/commons-lang/pull/1780
## Description
Fixes a calculation bug in `DurationFormatUtils.formatPeriod(long, long,
String, boolean, TimeZone)` where duration formatting with patterns containing
year (`y`) and day (`d`) tokens without month (`M`) tokens (e.g. `"y' years 'd'
days'"` or `"y'y 'd'd'"`) incorrectly inflates the duration by **+1 full year
(+365 days)** when spanning across a calendar year boundary that is less than a
full 12-month anniversary.
### Problem / Reproduction
Prior to this fix:
- **31 days** (`2024-12-15` to `2025-01-15`) was formatted as `"1 years 31
days"` (396 days instead of 31 days).
- **361 days** (`2024-01-15` to `2025-01-10`) was formatted as `"1 years 26
days"` (392 days instead of 361 days).
- **365 days** (`2024-02-29` to `2025-02-28`) was formatted as `"1 years 28
days"` (393 days instead of 365 days).
### Root Cause
1. `years` was initialized as `end.get(Calendar.YEAR) -
start.get(Calendar.YEAR)`.
2. When `M` was not present in `tokens`, the code rolled month differences
into `days`, but did not decrement `years` when less than a full 12-month
calendar year had elapsed.
3. `start` was not advanced to match the subtracted `years`, which caused
subsequent month-to-day accumulations to miscount intervening days across year
boundaries.
### Solution
1. When `M` is omitted and `y` is present:
- Check if a full calendar year has elapsed (`months < 0 || (months == 0
&& days < 0)`). If not, decrement `years`.
- Advance `start` by the elapsed `years` (`start.add(Calendar.YEAR, (int)
years)`).
2. Roll all remaining intervening months into `days` until `start.get(YEAR)
== end.get(YEAR) && start.get(MONTH) == end.get(MONTH)`.
3. Borrow any negative remaining `days` from
`start.getActualMaximum(Calendar.DAY_OF_MONTH)`.
### Tests Added & Verification
- Added `testFormatPeriodWithoutMonths()` to `DurationFormatUtilsTest.java`
verifying:
- Cross-year durations (< 1 year).
- Periods near 1 full year.
- Leap-year to non-leap-year boundaries (e.g. Feb 29 to Feb 28).
- Ran full test suite via Maven: all **46/46** tests passed with 0 failures
and 0 regressions.
--
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: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]