datetime/billing_cycle_utils library
Monthly billing-anniversary math with end-of-month clamping — roadmap #609.
Answers "when does the subscription bill this month?", "what is the next billing date on/after some instant?", and "which [start, end) cycle is a given day inside?" for a fixed monthly anchor day (1..31).
The hard case is an anchor past a short month's length: anchor 31 cannot bill
on February 31. The rule here is LAST-DAY CLAMPING — the anchor is clamped
down to the month's final day (Feb -> 28 or 29, April -> 30), so the bill
always lands on a real date and never silently rolls into the next month the
way DateTime(2024, 2, 31) would. All values are local date-only (the time
component is dropped); callers working in a single zone get stable results.
Functions
-
billingDateInMonth(
int year, int month, int anchorDay) → DateTime -
The billing date for
anchorDaywithinmonthofyear, with the anchor CLAMPED to the month's length so it is always a real date. -
billingSchedule(
DateTime start, int anchorDay, int count) → List< DateTime> -
countconsecutive monthly billing dates beginning with the next billing date on/afterstart, each clamped to its month's length. -
currentCycle(
DateTime on, int anchorDay) → ({DateTime end, DateTime start}) -
The half-open
[start, end)billing cycle that containsonforanchorDay. -
nextBillingDate(
DateTime from, int anchorDay) → DateTime -
The next billing date strictly on or after the date part of
fromforanchorDay.