# subscriptions.trial-end
A trial of N days that starts on day S covers S and the N - 1 days after it,
so the last free day is S + N - 1 and the first payment is taken on S + N. A
14-day trial starting 1 January is free up to and including 14 January and is
charged on 15 January. Both dates come back, because a sign-up page prints the
first ("your trial ends on 14 January") and the billing system schedules the
second, and deriving one from the other is where the off-by-one creeps in.
Trials are counted in days, never in months: a 30-day trial from 31 January
ends on 1 March in 2026 (2 March's charge), not on "28 February". If the offer
really is "one month free", the first charge is dates.add-months from the
start date and this capability is not the one to use.
A trial of 0 days is no trial: lastTrialDay is null and the first charge is on
the start date itself. A negative length is an error, as is an impossible
start date (2026-02-30), which the dates.add-days kernel refuses to parse.
This works on calendar dates. A trial that starts at 23:59 in one time zone
and is billed at midnight in another is a time-zone decision for the caller;
convert to the billing account's local date first.