Private
Public Access
1
0

Fix date display timezone shift and revert to standard monthly interest

formatDate was parsing UTC timestamps in local time, shifting dates
back a day in western timezones. Strip the time portion before parsing
so dates display correctly.

Revert interest calculation from daily accrual back to standard monthly
compounding (rate/12) with per-payment rounding. This matches how
mortgage servicers calculate interest and produces correct amortization
schedules.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Catherine Renelle
2026-02-14 17:26:55 -05:00
parent 0f3ad89c59
commit 428e18bb41
2 changed files with 5 additions and 11 deletions
+1 -1
View File
@@ -5,7 +5,7 @@ export function formatCurrency(amount: number): string {
}
export function formatDate(date: string): string {
return format(parseISO(date), 'MM/dd/yyyy')
return format(parseISO(date.split('T')[0]), 'MM/dd/yyyy')
}
export function formatDateTime(date: string): string {
+4 -10
View File
@@ -118,12 +118,11 @@ public class LoanService : ILoanService
// Build new schedule with extra payments
var balance = Math.Abs(account.Balance);
var dailyRate = l.InterestRate / 100m / 365m;
var monthlyRate = l.InterestRate / 100m / 12m;
var extraMonthly = request.ExtraMonthlyPayment ?? 0;
var basePayment = l.MonthlyPayment - (l.EscrowAmount ?? 0);
var now = DateTime.UtcNow;
var startDate = new DateTime(now.Year, now.Month, l.OriginationDate.Day, 0, 0, 0, DateTimeKind.Utc);
var previousDate = startDate;
var newEntries = new List<AmortizationEntryResponse>();
int paymentNum = 0;
@@ -139,15 +138,13 @@ public class LoanService : ILoanService
{
paymentNum++;
var paymentDate = startDate.AddMonths(paymentNum);
var days = (paymentDate - previousDate).Days;
var interest = balance * dailyRate * days;
var interest = Math.Round(balance * monthlyRate, 2);
var principal = Math.Min(basePayment + extraMonthly - interest, balance);
if (principal < 0) principal = 0;
balance -= principal;
if (balance < 0.01m) balance = 0;
previousDate = paymentDate;
newEntries.Add(new AmortizationEntryResponse(
paymentNum, paymentDate, principal + interest + (l.EscrowAmount ?? 0),
@@ -188,20 +185,17 @@ public class LoanService : ILoanService
{
var entries = new List<AmortizationEntry>();
var balance = loan.OriginalBalance;
var dailyRate = loan.InterestRate / 100m / 365m;
var monthlyRate = loan.InterestRate / 100m / 12m;
var payment = loan.MonthlyPayment - (loan.EscrowAmount ?? 0);
var extra = loan.ExtraPayment ?? 0;
var previousDate = loan.OriginationDate.AddMonths(-1);
for (int i = 1; i <= loan.TermMonths && balance > 0; i++)
{
var paymentDate = loan.OriginationDate.AddMonths(i - 1);
var days = (paymentDate - previousDate).Days;
var interest = balance * dailyRate * days;
var interest = Math.Round(balance * monthlyRate, 2);
var principal = Math.Min(payment + extra - interest, balance);
balance -= principal;
if (balance < 0.01m) balance = 0;
previousDate = paymentDate;
entries.Add(new AmortizationEntry
{