The script is made with Laravel and I understand that this can be solved with several if statements but I wonder if there is a simple function which I am missing.
A subscription should be charged on the day before it runs out. So if a subscription started on the 31st it will be billed on the 30th. If the month has 30 days it will be billed on the 29.
If I add another month to today with addMonthsNoOverflow(1) then in the third month the user will be charged on the 29th instead of 30th.
is there some function which would allow me to set a fake date like the 30th February and then add a month to it?
You could create a Carbon Macro that accepts a day and returns that day unless it does not exist in that month in which case it returns the last day instead, e.g:
Carbon::macro('thisDayOrLast', function ($day) {
$last = $this->copy()->lastOfMonth();
$this->day = ($day > $last->day) ? $last->day : $day;
return $this;
});
You would store the original subscription date and then to determine what date they should be billed this month you'd do something like:
Carbon::today()->thisDayOrLast($subscription->day);
And if you wanted to provide a user with a list of every day they'll be billed for the next 12 months you could do something like:
$start = Carbon::today();
$subscription = Carbon::parse('2017-12-31');
foreach (range(1, 12) as $month) {
$day = $start->addMonthNoOverflow()->thisDayOrLast($subscription->day);
echo "You will be billed on {$day} in month {$month}\n";
}
You will be billed on 2018-05-31 00:00:00 in month 1
You will be billed on 2018-06-30 00:00:00 in month 2
You will be billed on 2018-07-31 00:00:00 in month 3
You will be billed on 2018-08-31 00:00:00 in month 4
You will be billed on 2018-09-30 00:00:00 in month 5
You will be billed on 2018-10-31 00:00:00 in month 6
You will be billed on 2018-11-30 00:00:00 in month 7
You will be billed on 2018-12-31 00:00:00 in month 8
You will be billed on 2019-01-31 00:00:00 in month 9
You will be billed on 2019-02-28 00:00:00 in month 10
You will be billed on 2019-03-31 00:00:00 in month 11
You will be billed on 2019-04-30 00:00:00 in month 12
Note: Macros are a new Carbon feature, if you're on an older version of Laravel you may need to update Carbon using composer update
.