2025-11-10
This paper reconstructs the Norwegian delay–interest calculator from the government API. The official period-based day–count model is formalized, a Gregorian-year approximation is derived from the calendar leap-year rule, and the algebraic difference between the two methods is expressed without simplification. A five–year example (including leap years) is computed and summarized in a numerical table. Python excerpts show how the JSON rate periods drive the segmentation.
Norwegian delay interest is accrued per calendar day and segmented by legally defined interest-rate periods. The official calculator uses the number of days in the current calendar year (\(365\) or \(366\)) as divisor inside each segment. A secondary approximation treats each year as the Gregorian mean length. The goal is to (i) document the API structure that enables reconstruction, (ii) derive both models algebraically, and (iii) quantify their difference over a long interval containing leap years.
Interest periods are fetched from the same endpoint as the official calculator:
https://www.regjeringen.no/api/interestCalculatorApi/InitData?language=no&crefid=3025889
The relevant part of the response is the DateInterest
array. A generalized structure is:
{ "status": 200, "message": "", "data": { "Text": { ... }, "DateInterest": [ { "Date": "YYYY-MM-DD", "Interest": "0.XXXX" }, { "Date": "YYYY-MM-DD", "Interest": "0.XXXX" }, ... { "Date": "YYYY-MM-DD", "Interest": "n/a" } ] } }
Each numeric entry defines the start date of a new legal rate period
and its annual rate. Future "n/a" entries are ignored.
For any calculation interval:
\(P\): principal (amount overdue), in NOK.
\(t_0\): due date (start of delay).
\(t_1\): payment date (end of delay).
\(i \in \{1,\dots,n\}\): index over API-defined interest periods intersecting \([t_0,t_1]\).
\(r_i\): annual interest rate in period \(i\), as decimal (e.g. 0.125).
\(d_i\): number of delay days falling inside period \(i\).
\(D_i\): year-length divisor used in period \(i\).
Interest in period \(i\) is \[I_i(P,r_i,d_i,D_i) = P \cdot r_i \cdot \frac{d_i}{D_i},\] with legal divisor \[D_i = \begin{cases} 365 & \text{if the segment lies in a non-leap year}, \\ 366 & \text{if the segment lies in a leap year}. \end{cases}\]
Total official interest is the sum over all intersecting periods: \[I_{\text{official}}(P,\{r_i\},\{d_i\},\{D_i\}) = \sum_{i=1}^{n} P \cdot r_i \cdot \frac{d_i}{D_i}.\]
The Gregorian calendar defines leap years as:
every year divisible by 4 is a leap year,
except years divisible by 100,
but years divisible by 400 are leap years.
Over a 400-year cycle: \[\text{leap years} = 400/4 - 400/100 + 400/400 = 100 - 4 + 1 = 97.\] Thus the mean year length is \[D_{\text{greg}} = \frac{400 \cdot 365 + 97}{400} = 365 + \frac{97}{400} = 365.2425.\]
In the Gregorian approximation, every period uses the constant divisor \(D_{\text{greg}}\): \[I_{\text{greg}}(P,\{r_i\},\{d_i\}) = \sum_{i=1}^{n} P \cdot r_i \cdot \frac{d_i}{D_{\text{greg}}}.\]
Define the difference as \[\Delta I(P,\{r_i\},\{d_i\},\{D_i\}) = I_{\text{official}} - I_{\text{greg}}.\]
Substituting the two sums: \[\Delta I = \sum_{i=1}^{n} \left(P \cdot r_i \cdot \frac{d_i}{D_i}\right) - \sum_{i=1}^{n} \left(P \cdot r_i \cdot \frac{d_i}{D_{\text{greg}}}\right).\]
Grouping by period: \[\Delta I = \sum_{i=1}^{n} \left[ P \cdot r_i \cdot d_i \cdot \left(\frac{1}{D_i}\right) - P \cdot r_i \cdot d_i \cdot \left(\frac{1}{D_{\text{greg}}}\right) \right].\]
The script uses DateInterest to segment \([t_0,t_1]\):
for i, (rate_date, rate) in enumerate(rates): next_date = rates[i+1][0] if i+1 < len(rates) else payment_date if due_date < rate_date: continue if next_date > payment_date: next_date = payment_date days = (next_date - due_date).days year_days = Decimal("365.2425") if gregorian else ( Decimal("366") if calendar.isleap(due_date.year) else Decimal("365")) interest = P * rate * Decimal(days) / year_days due_date = next_date
Using the API periods over \(t_0=\text{01.01.2019}\) to \(t_1=\text{01.01.2024}\) with \(P=100\,000\) NOK, interest is accumulated per period exactly as in the script. The Gregorian column uses \[I_{i,\text{greg}} = P\, r_i\,\frac{d_i}{D_{\text{greg}}},\qquad D_{\text{greg}}=365.2425,\] while the official column uses \(D_i\in\{365,366\}\) by calendar year.
| From date | \(r_i\) (%) | \(d_i\) | \(I_i\) off. | Acc. off. | \(I_i\) greg. | Acc. greg. |
|---|---|---|---|---|---|---|
| 01.01.2019 | 8.75 | 181 | 4 339.04 | 4 339.04 | 4 331.42 | 4 331.42 |
| 01.07.2019 | 9.25 | 184 | 4 663.01 | 9 002.05 | 4 651.87 | 8 983.29 |
| 01.01.2020 | 9.50 | 182 | 4 724.04 | 13 726.09 | 4 710.49 | 13 693.78 |
| 01.07.2020 | 8.00 | 184 | 4 021.86 | 17 747.95 | 4 012.33 | 17 706.11 |
| 01.01.2021 | 8.00 | 181 | 3 967.12 | 21 715.07 | 3 959.24 | 21 665.35 |
| 01.07.2021 | 8.00 | 184 | 4 032.88 | 25 747.95 | 4 023.21 | 25 688.56 |
| 01.01.2022 | 8.50 | 181 | 4 215.07 | 29 963.02 | 4 206.25 | 29 894.81 |
| 01.07.2022 | 9.25 | 184 | 4 663.01 | 34 626.03 | 4 651.87 | 34 546.68 |
| 01.01.2023 | 10.75 | 181 | 5 330.82 | 39 956.85 | 5 317.57 | 39 864.25 |
| 01.07.2023 | 11.75 | 184 | 5 923.29 | 45 880.14 | 5 908.38 | 45 772.63 |
Thus, \[I_{\text{official}} = 45\,880.14\ \text{kr},\qquad I_{\text{greg}} = 45\,772.63\ \text{kr},\] so \[\Delta I = I_{\text{official}}-I_{\text{greg}} = 107.51\ \text{kr}.\]
Consider a full Gregorian 400-year cycle indexed by years \(y=1,\dots,400\). Let the (unknown) annual rates be collected in a vector \[\mathbf{r} = [r_1,\dots,r_{400}]^\top,\] and define the diagonal matrix of legal year lengths \[\mathbf{D} = \mathrm{diag}(D_1,\dots,D_{400}),\qquad D_y\in\{365,366\}.\] Over a complete year, the day count equals the divisor: \(d_y=D_y\).
\[I_{\text{off},400} = \sum_{y=1}^{400} P\, r_y\,\frac{D_y}{D_y} = P \sum_{y=1}^{400} r_y = P\,\mathbf{1}^\top\mathbf{r}.\]
\[I_{\text{greg},400} = \sum_{y=1}^{400} P\, r_y\,\frac{D_y}{D_{\text{greg}}} = \frac{P}{D_{\text{greg}}}\sum_{y=1}^{400} r_y D_y = \frac{P}{D_{\text{greg}}}\,\mathbf{1}^\top\mathbf{D}\mathbf{r}.\]
Since the Gregorian rule yields \(97\) leap years per 400 years, \[\sum_{y=1}^{400} D_y = 400\cdot 365 + 97 = 400\,D_{\text{greg}}.\]
Therefore, \[I_{\text{off},400}=I_{\text{greg},400} \quad\Longleftrightarrow\quad \mathbf{1}^\top\mathbf{D}\mathbf{r} = D_{\text{greg}}\,\mathbf{1}^\top\mathbf{r}.\]
This equality holds for all unknown rate vectors \(\mathbf{r}\) only if \(\mathbf{D}=D_{\text{greg}}\mathbf{I}\), which is false because \(D_y\) alternates between \(365\) and \(366\). Hence, in general, \[I_{\text{off},400}\neq I_{\text{greg},400}.\]
However, two important cases give equality:
Constant (or leap-year-independent) rates: if \(r_y=r\) for all \(y\), then \[I_{\text{off},400}=400Pr, \qquad I_{\text{greg},400} =\frac{P r}{D_{\text{greg}}}\sum D_y =\frac{P r}{D_{\text{greg}}}\cdot 400D_{\text{greg}} =400Pr.\]
Rates uncorrelated with leap years: if the mean rate across leap and non-leap years is the same, the weighted sum \(\mathbf{1}^\top\mathbf{D}\mathbf{r}\) equals \(D_{\text{greg}}\,\mathbf{1}^\top\mathbf{r}\), giving approximate equality.
Both the official period model and the Gregorian model compute delay interest on the form \[I = P \, r \, \frac{d}{D},\] where \(P\) is the principal, \(r\) the annual interest rate, \(d\) the number of days in a segment, and \(D\) the year divisor. The two methods differ only in the choice of \(D\): \[D_{\text{off}} \in \{365, 366\}, \qquad D_{\text{greg}} = 365.2425.\]
Because both expressions are affine in \(r\), their derivatives are simple:
\[\frac{\partial I_{\text{off}}}{\partial r} = P \frac{d}{D_{\text{off}}}, \qquad \frac{\partial I_{\text{greg}}}{\partial r} = P \frac{d}{365.2425}.\]
Thus the two slopes differ only by the reciprocal of their respective year lengths. Define the slope difference: \[\Delta'(r) = \frac{\partial I_{\text{off}}}{\partial r} - \frac{\partial I_{\text{greg}}}{\partial r} = P d \left(\frac{1}{D_{\text{off}}} - \frac{1}{365.2425}\right).\]
Recall the slope difference between the two models with respect to \(r\): \[\Delta'(r) = \frac{\partial I_{\text{off}}}{\partial r} - \frac{\partial I_{\text{greg}}}{\partial r} = P d \left(\frac{1}{D_{\text{off}}} - \frac{1}{D_{\text{greg}}}\right),\] where \(D_{\text{off}}\in\{365,366\}\) depends on whether the current year is leap, and \(D_{\text{greg}}=365.2425\) is constant.
Over a full Gregorian 400-year cycle, there are exactly \[97 \text{ leap years} \quad\text{and}\quad 303 \text{ non-leap years}.\] Hence the total number of days in the cycle is \[S = 303\cdot 365 + 97\cdot 366 = 400\cdot 365 + 97 = 146097.\] Therefore the average official year length is \[\bar D = \frac{S}{400} = \frac{146097}{400} = 365.2425 = D_{\text{greg}}.\]
Assume the annual rate does not depend on leap-year status (e.g. constant \(r\), or rates whose mean is the same in leap and non-leap years). Then the interest in each year has the same proportional dependence on \(r\), so we can compare total slopes across the 400 years by summing year-slopes:
Official total slope over 400 years: \[\sum_{y=1}^{400} \frac{\partial I_{\text{off},y}}{\partial r} = \sum_{y=1}^{400} P \frac{d_y}{D_y}.\] But for a full year, \(d_y=D_y\), so \[\sum_{y=1}^{400} \frac{\partial I_{\text{off},y}}{\partial r} = \sum_{y=1}^{400} P \frac{D_y}{D_y} = 400P.\]
Gregorian total slope over 400 years: \[\sum_{y=1}^{400} \frac{\partial I_{\text{greg},y}}{\partial r} = \sum_{y=1}^{400} P \frac{d_y}{D_{\text{greg}}} = \frac{P}{D_{\text{greg}}}\sum_{y=1}^{400} D_y = \frac{P}{365.2425}\cdot 146097 = \frac{P}{365.2425}\cdot (400\cdot 365.2425) = 400P.\]
Thus, \[\sum_{y=1}^{400} \Delta'(r)_y = \sum_{y=1}^{400} \left( \frac{\partial I_{\text{off},y}}{\partial r} - \frac{\partial I_{\text{greg},y}}{\partial r} \right) = 400P - 400P = 0.\]
When the official model uses \(D_{\text{off}} = 365\), \[\Delta'(r) > 0: \quad \text{the official interest grows \emph{faster} with respect to } r.\]
When the official model uses \(D_{\text{off}} = 366\), \[\Delta'(r) < 0: \quad \text{the Gregorian interest grows \emph{faster} with respect to } r.\]
Because leap years occur 97 times per 400 years, these sign changes balance out exactly over a full 400-year cycle.
For any fixed period length \(d\), both \(I_{\text{off}}\) and \(I_{\text{greg}}\) are strictly linear functions of \(r\). There is no curvature; their graphs are straight lines with slightly different slopes: \[I_{\text{off}}(r) = r \left(P \frac{d}{D_{\text{off}}}\right), \qquad I_{\text{greg}}(r) = r \left(P \frac{d}{365.2425}\right).\]
This explains two empirical facts:
The difference between the two models over any sub-400-year interval accumulates linearly in \(r\), but the slope switches at each leap year.
Over the complete 400-year cycle, the weighted average of the official slopes matches the Gregorian slope: \[\frac{303}{365} + \frac{97}{366} = 365.2425,\] giving perfect long-run equivalence between the two methods.
The government’s delay–interest calculator imposes a strict upper bound on the principal, \[0 < P < 100\,000\,000\,000,\] as defined explicitly in the API’s error message:
"Beløpet må være større enn 0 og mindre enn 100.000.000.000."
This restriction is administrative rather than mathematical. The interest function is linear in \(P\), \[I(P) = P \sum_{i=1}^{n} r_i\,\frac{d_i}{D_i},\] so no instability occurs for large \(P\). The reverse-engineered script therefore removes the bound, allowing:
arbitrarily large principal values,
simulation of extreme cases,
actuarial and long-horizon modelling,
stress-testing under large debts.
This makes the offline version strictly more general than the official calculator.
The difference between the official model and the Gregorian model arises solely from the divisor term \(D_i\). Within any multi-year interval shorter than the 400-year Gregorian cycle, the official model alternates between \(365\)- and \(366\)-day denominators, giving a piecewise-varying daily interest rate. The Gregorian approximation removes this fluctuation by using a constant \(365.2425\)-day year. The consequence is a small but persistent difference:
\[\Delta I = P \sum_{i=1}^{n} r_i d_i \left(\frac{1}{D_i} - \frac{1}{365.2425}\right),\] which changes sign depending on whether the segment lies in a leap year.
For a debtor over short horizons (months or a few years), this difference is negligible but not zero. Over long horizons the discrepancy becomes visible, though always bounded because the term inside parentheses is small.
From a legal standpoint, only the period-based model is valid. From a mathematical standpoint, the Gregorian model is a smoothing of the divisor term and is exactly equivalent when viewed over a complete 400-year cycle.
The governmental calculator forbids principal amounts above \(100\,000\,000\,000\) NOK. This restriction has no mathematical justification—linearity in \(P\) ensures stability for arbitrarily large inputs. By removing this constraint, the offline implementation unlocks analytical and actuarial applications that the official tool cannot perform.
The official period-based method and the Gregorian-average method differ only in the treatment of the year divisor. When interest is accumulated across the full 400-year Gregorian cycle, both yield exactly the same total delay interest for any sequence of annual rates. This equivalence arises because the Gregorian calendar contains precisely \[146097 = 400 \cdot 365 + 97\] days, giving the mean divisor \[\frac{146097}{400} = 365.2425,\] which matches the constant divisor in the Gregorian approximation. Over a complete cycle, the sum of period divisors in the official model equals \(400 \cdot 365.2425\), making the two approaches mathematically identical in the long run.
For intervals shorter than 400 years the two methods diverge, with the sign of the difference determined by the placement of leap years. Because \[\frac{1}{365} > \frac{1}{365.2425} > \frac{1}{366},\] the official model produces slightly higher interest in non-leap years and slightly lower interest in leap years. These effects accumulate but remain small relative to the principal.
The official calculator imposes a hard upper bound of \(100\,000\,000\,000\) NOK on the principal. This limitation has no mathematical basis—since the interest function is linear in \(P\), the formulas remain well behaved for arbitrarily large values. By removing this constraint, the offline implementation becomes a strictly more general and analytically useful tool while remaining a faithful reconstruction of the legal model and its period segmentation.
Wikipedia. (2024). Gregorian calendar. Retrieved from https://en.wikipedia.org/wiki/Gregorian_calendar
Wikipedia. (2024). Leap year. Retrieved from https://en.wikipedia.org/wiki/Leap_year
Wikipedia. (2024). Day count convention. Retrieved from https://en.wikipedia.org/wiki/Day_count_convention
Wikipedia. (2024). Time value of money. Retrieved from https://en.wikipedia.org/wiki/Time_value_of_money
Lovdata. (2024). Forsinkelsesrenteloven. Retrieved from https://lovdata.no/dokument/NL/lov/1976-12-17-100
Royal Ministry of Finance. (2024). Kalkulator for forsinkelsesrenten. Retrieved from https://www.regjeringen.no/no/tema/okonomi-og-budsjett/renter/forsinkelsesrente-/kalkulator-for-forsinkelsesrenten/id3025884/
Royal Ministry of Finance. (2024). Interest Calculator API. Endpoint: https://www.regjeringen.no/api/interestCalculatorApi/InitData
Wikipedia. (2024). Interest. Retrieved from https://en.wikipedia.org/wiki/Interest
Local reproduction. https://app.eipi.dev/forsinkelsesrente