Functional Weave
Code in TypeScript

property.rent-proration@1.0.0

README.md

1,973 bytes · view raw

# property.rent-proration

Rent for a part month: the first month of a tenancy that starts mid-month,
the last month of one that ends mid-month, or a refund of rent paid in
advance. Both dates are inclusive, so 1 to 15 January is 15 days.

There are two conventions in use, and they give different answers, so the
method is an argument and never a guess:

- **annual-daily**: a daily rate of monthly rent × 12 ÷ 365, times the days.
  This is what most letting agents and tenancy agreements in England use,
  because every day costs the same whatever the month.
  £1,000 a month for 15 days is £493.15.
- **calendar-month**: a daily rate of monthly rent ÷ the number of days in
  the month the day falls in. A full calendar month always comes to exactly
  one month's rent. £1,000 a month for 1 to 15 January is 15/31 of £1,000,
  £483.87. A period that crosses a month end is charged at each month's own
  daily rate: 20 January to 10 February is 12/31 + 10/28 of a month.

## Rounding happens once

Each method is computed as an exact fraction and rounded half-up (away from
zero) to the penny only at the end. The daily rate is never rounded first:
£1,000 × 12 ÷ 365 is £32.8767…, and rounding that to £32.88 before
multiplying by 15 days would give £493.20 instead of £493.15.

## Edge cases and limits

- annual-daily does not know about leap years: 29 February is one more day
  at the same rate, and a full 28-day February is 28/365 of a year, not one
  month's rent. That is the convention, not a bug; use calendar-month if a
  whole month must be exactly the monthly rent.
- `toDate` before `fromDate` is an error, as is a period longer than 366
  days: this is for part months, and a longer span is whole months plus a
  part month.
- A negative monthly rent gives a negative answer, rounded symmetrically.
- The monthly rent may be at most £10,000,000 (1,000,000,000 minor units),
  which keeps every intermediate exact in all three languages.