Skip to content

Instantly share code, notes, and snippets.

@inxilpro
Created March 9, 2022 17:38
Show Gist options
  • Save inxilpro/2139ed71ef13795e82a0c067186e5d8d to your computer and use it in GitHub Desktop.
Save inxilpro/2139ed71ef13795e82a0c067186e5d8d to your computer and use it in GitHub Desktop.
<?php
class MonthlyPlan
{
public int $length = 1;
public string $unit = 'month';
public function normalizeBillingPeriod(Subscription $subscription, Carbon $charge_at): array
{
// First, we'll naively compute the end of the billing period (assuming the timing is 100% accurate)
$period_ends_at = $charge_at->add(unit: $this->unit, value: $this->length, overflow: false);
// Next, we get the rounded number of months from the start of the subscription to the date of the charge
$months_elapsed = round($subscription->starts_at->floatDiffInMonths($charge_at));
// Now we need the billing period length in months. Because plans can be on any schedule, we
// will compute this dynamically with rounding to account for any leap year rounding issues
$period_months = round($charge_at->floatDiffInMonths($period_ends_at));
// Finally, we can compute the actual range of the billing period
$period_starts_at = $subscription->starts_at->addMonthsNoOverflow($months_elapsed);
$period_ends_at = $subscription->starts_at->addMonthsNoOverflow($months_elapsed + $period_months);
return [$period_starts_at, $period_ends_at];
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment