European Day Count
Subtracting one date from another is the easy part the model gets for free. The hidden test is the convention: a standard way of counting days for interest treats the calendar as regular and rewrites any date that lands on the 31st, with a rule that is simpler and more uniform than the variant most builds reach for by default.
You are building the day-count primitive at the core of an interest calculation. It is handed two calendar dates and returns, as a single integer, the number of days between them under the convention used to settle interest. This count later multiplies into a rate, so it must match the convention exactly, not approximately.
Implement a function dayCount(startISO, endISO). The dates arrive as 'YYYY-MM-DD' strings and the start date is never after the end date; equal dates return 0. The naive answer counts the literal calendar days between the two dates, but that is not how this kind of interest is settled. The entire result hinges on a single modeling choice you must make and pin down precisely.
Specify which day-count convention governs and state its rule exactly. The convention treats every month as a uniform length and every year as a uniform length rather than counting the calendar day by day, and it carries a specific adjustment for any date that falls on the 31st of a month. Be careful: there is more than one widely used convention in this family, and they differ precisely in how they handle the 31st. One applies its end-of-month adjustment only conditionally, depending on the other date; another applies it to each date on its own, unconditionally. Decide which one governs, state how it counts a uniform month and year, state exactly when a day on the 31st is rewritten and to what, and write it as something a deterministic test could check. A calculator that counts actual calendar days, or that uses the conditional variant, will disagree with the convention whenever a date lands on the 31st.
From 2024-01-15 to 2024-03-31, counting actual calendar days gives 76. The convention that rewrites any 31st to a 30 unconditionally gives 75. A convention that only rewrites the 31st conditionally would also land on 76 here, so the unconditional rule is exactly what separates the answers.
- dayCount(startISO, endISO) returning an integer number of days; equal dates return 0.
- Dates are 'YYYY-MM-DD' strings with start no later than end.
- A clean period that avoids the 31st agrees across the common conventions.
The functional tests are shown, and the model usually clears them on its own. The hidden tests are the twists this kind of system is full of. They are not listed. Your spec only passes them if it already knows where this domain breaks.
151 chars