Add COUP* coupon date functions#74
Conversation
Implements COUPDAYBS, COUPDAYS, COUPDAYSNC, COUPNCD, COUPNUM and COUPPCD with shared date/basis helpers, wires them into dispatch and static analysis, adds parser fallbacks, tests, and docs.
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 2 potential issues.
Bugbot Autofix is OFF. To automatically fix reported issues with Cloud Agents, enable Autofix in the Cursor dashboard.
This is the final PR Bugbot will review for you during this billing cycle
Your free Bugbot reviews will reset on March 18
Details
You are on the Bugbot Free tier. On this plan, Bugbot will review limited PRs each billing cycle.
To receive Bugbot reviews on all of your PRs, visit the Cursor dashboard to activate Pro and start your 14-day free trial.
|
|
||
| fn is_leap_year(year: i32) -> bool { | ||
| (year % 4 == 0) && (year % 100 != 0 || year % 400 == 0) | ||
| } |
There was a problem hiding this comment.
Duplicated is_leap_year function across modules
Low Severity
The is_leap_year function in financial.rs is identical to the existing one in date_and_time.rs. Both implementations have the same signature fn is_leap_year(year: i32) -> bool and the same logic (year % 4 == 0) && (year % 100 != 0 || year % 400 == 0). This is redundant code that increases maintenance burden - if a bug were found in this logic, it would need to be fixed in both places.
| // Rule 1: If both date A and B fall on the last day of February, then date B will be changed to the 30th | ||
| if is_last_day_of_february(start) && is_last_day_of_february(end) { | ||
| d2 = DAYS_IN_MONTH_360; | ||
| } |
There was a problem hiding this comment.
US 30/360 February rule differs from existing implementation
High Severity
The days360_us function's Rule 1 only adjusts end date to 30 when BOTH dates are the last day of February. However, the existing fn_days360 adjusts end date to 30 when end is last day of February AND start day became 30 (from being 31st OR Feb last day). This causes inconsistent results: for dates like March 31 to Feb 28, fn_days360 returns 690 but days360_us returns 688. COUPDAYBS and COUPDAYSNC with basis=0 will produce different results than DAYS360 for the same date ranges.


Summary
Test plan
cargo test --package ironcalc_base couponNote
Medium Risk
Adds new date/day-count financial computations (including 30/360 US/EU February edge-case rules), which can subtly affect numeric results and error behavior for workbook evaluations.
Overview
Adds support for Excel coupon-date functions
COUPDAYBS,COUPDAYS,COUPDAYSNC,COUPNCD,COUPNUM, andCOUPPCD, including shared helpers for coupon period selection and day-count conventions (30/360 US/EU and actual).Wires the new functions through parsing (including
_xlfn.fallback), function dispatch/name mapping, and static analysis signatures/return types. Includes a newtest_fn_couponsuite covering happy paths, argument validation, an actual-day-count vs fixed-day-countCOUPDAYSfix, and February/leap-year edge cases; docs are updated to mark these functions as available and link to stub pages.Written by Cursor Bugbot for commit 23fffdf. Configure here.