Skip to content

fix calculate_relative_offset year offset from Feb 29 - #9968

Merged
ThomasWaldmann merged 1 commit into
borgbackup:masterfrom
ThomasWaldmann:fix-9967-leap-year
Jul 29, 2026
Merged

fix calculate_relative_offset year offset from Feb 29#9968
ThomasWaldmann merged 1 commit into
borgbackup:masterfrom
ThomasWaldmann:fix-9967-leap-year

Conversation

@ThomasWaldmann

Copy link
Copy Markdown
Member

Fixes #9967.

Routes the y case in calculate_relative_offset through offset_n_months(from_ts, offset * 12) as suggested in the issue. Result: Feb 29 + Ny no longer crashes when the target year is not a leap year — the day is clamped to the target month's last day (Feb 28 in a non-leap year, Feb 29 in a leap year).

Also extended offset_n_months to preserve hour/minute/second/microsecond of from_ts — otherwise routing the year case through it would have silently dropped time-of-day (and the month case had the same latent gap).

Regression tests added in src/borg/testsuite/helpers/time_test.py.

…up#9967

Reusing offset_n_months for the year case naturally clamps the day to
the last day of the target month, so Feb 29 + Ny no longer crashes when
the target year is not a leap year.

Also preserve h/m/s/us in offset_n_months so year/month offsets keep the
time-of-day (previously dropped, now covered by tests).
@codecov

codecov Bot commented Jul 29, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 85.72%. Comparing base (a50eb6f) to head (471f451).
⚠️ Report is 8 commits behind head on master.
✅ All tests successful. No failed tests found.

Additional details and impacted files
@@            Coverage Diff             @@
##           master    #9968      +/-   ##
==========================================
+ Coverage   85.70%   85.72%   +0.02%     
==========================================
  Files          95       95              
  Lines       16815    16845      +30     
  Branches     2577     2581       +4     
==========================================
+ Hits        14411    14441      +30     
  Misses       1668     1668              
  Partials      736      736              

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

@ThomasWaldmann
ThomasWaldmann merged commit 9aeffcc into borgbackup:master Jul 29, 2026
19 checks passed
@ThomasWaldmann
ThomasWaldmann deleted the fix-9967-leap-year branch July 29, 2026 21:27
@PhrozenByte

PhrozenByte commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

Also extended offset_n_months to preserve hour/minute/second/microsecond of from_ts

In case a borg2 beta tester notices a regression: this slightly changes the behavior of borg2 repo-list --oldest/--newest/--older/--newer (these selectors don't exist in Borg 1). Previously, running borg2 repo-list --newer 1m (assuming "now" is 2026-07-29 22:00:00) would also include an archive created at 2026-06-29 00:00:00. This is no longer the case, the cut-off date is now 2026-06-29 22:00:00 instead of 2026-06-29 00:00:00.

Since borg2 is still in beta and the new behavior better matches the behavior of all other intervals, this is just a heads-up. IMHO there's no need to change or document this.

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.

borg2: ValueError due to leap year confusion in calculate_relative_offset()

2 participants