Skip to content

Fix humanize reporting "a year ago" for ~31-day deltas in same month#1247

Open
bysiber wants to merge 2 commits intoarrow-py:masterfrom
bysiber:fix/humanize-month-boundary-gap
Open

Fix humanize reporting "a year ago" for ~31-day deltas in same month#1247
bysiber wants to merge 2 commits intoarrow-py:masterfrom
bysiber:fix/humanize-month-boundary-gap

Conversation

@bysiber
Copy link
Copy Markdown

@bysiber bysiber commented Feb 20, 2026

Summary

Fix a gap in the humanize() if/elif chain that causes ~31-day deltas within the same calendar month to report "a year ago" instead of "a month ago".

Problem

In the auto-granularity branch of humanize(), there's a gap between the "weeks" and "months" conditions:

elif calendar_months < 1 and diff < self._SECS_PER_MONTH:
    # "X weeks ago"

elif calendar_months >= 1 and diff < self._SECS_PER_YEAR:
    # "X months ago"

elif diff < self._SECS_PER_YEAR * 2:
    # "a year ago"

When diff >= _SECS_PER_MONTH (30.5 days) and calendar_months < 1 (both dates in the same calendar month), neither the "weeks" nor the "months" condition is satisfied:

  • "weeks" requires diff < _SECS_PER_MONTHFalse
  • "months" requires calendar_months >= 1False

Execution falls through to the "a year ago" branch.

Reproduction

import arrow

start = arrow.Arrow(2023, 1, 1)
end = arrow.Arrow(2023, 1, 31, 14, 0, 0)  # 30.5+ days later, same month

start.humanize(end)  # Returns "a year ago" instead of "a month ago"

This affects all 7 months with 31 days (January, March, May, July, August, October, December) when comparing timestamps near the boundaries of the same month.

Fix

Add an explicit branch for this case: when calendar_months < 1 but diff >= _SECS_PER_MONTH, report the delta as "a month".

When the time difference exceeds _SECS_PER_MONTH (30.5 days) but
calendar_months is still 0 (both dates in the same calendar month),
no branch in the if/elif chain matched:

- "weeks" requires diff < _SECS_PER_MONTH -> False
- "months" requires calendar_months >= 1 -> False

Execution fell through to the "year" branch, so a ~31-day
difference within the same month reported "a year ago".

This affects all 7 months with 31 days (Jan, Mar, May, Jul, Aug,
Oct, Dec) when comparing dates near the start and end of the
same month.

Add an explicit branch for this case that reports "a month" when
diff >= _SECS_PER_MONTH but calendar_months < 1.
@codecov
Copy link
Copy Markdown

codecov bot commented Feb 20, 2026

Codecov Report

❌ Patch coverage is 0% with 2 lines in your changes missing coverage. Please review.
✅ Project coverage is 99.91%. Comparing base (b423717) to head (9551f97).

Files with missing lines Patch % Lines
arrow/arrow.py 0.00% 1 Missing and 1 partial ⚠️
Additional details and impacted files
@@             Coverage Diff             @@
##            master    #1247      +/-   ##
===========================================
- Coverage   100.00%   99.91%   -0.09%     
===========================================
  Files           10       10              
  Lines         2315     2317       +2     
  Branches       358      359       +1     
===========================================
  Hits          2315     2315              
- Misses           0        1       +1     
- Partials         0        1       +1     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@krisfremen
Copy link
Copy Markdown
Member

@bysiber please add tests, otherwise this looks to be good

@bysiber
Copy link
Copy Markdown
Author

bysiber commented Feb 20, 2026

Added a test, it checks the case where you have a ~31-day delta between Jan 15 and Feb 15, where calendar_months can round to 0 but the actual elapsed time exceeds one month. Without the fix, this case fell through to the wrong branch.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants