Carbon 用于计算订阅账单日。 addMonthsNoOverflow(1) 但考虑订阅是否在 31 日开始

Carbon for calculating subscription bill day. addMonthsNoOverflow(1) but considering if subscription was started on a 31st

脚本是用 Laravel 制作的,我知道这可以用几个 if 语句来解决,但我想知道是否有一个我缺少的简单函数。

订阅应在到期前一天收费。因此,如果订阅在 31 日开始,它将在 30 日计费。如果该月有 30 天,则将在 29 日计费。

如果我使用 addMonthsNoOverflow(1) 在今天增加一个月,那么在第三个月,用户将在 29 日而不是 30 日收费。

有什么功能可以让我设置一个像 2 月 30 日这样的假日期,然后再加一个月吗?

您可以创建一个 Carbon Macro 接受一天和 returns 那一天,除非它在那个月不存在,在这种情况下它 returns 最后一天,例如:

Carbon::macro('thisDayOrLast', function ($day) {
    $last = $this->copy()->lastOfMonth();

    $this->day = ($day > $last->day) ? $last->day : $day;

    return $this;
});

您可以存储原始订阅日期,然后确定他们应该在本月的哪个日期进行结算,您可以执行以下操作:

Carbon::today()->thisDayOrLast($subscription->day);

如果您想为用户提供一个列表,列出他们将在接下来的 12 个月内每天都需要支付的费用,您可以这样做:

$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

注意:宏是 Carbon 的一项新功能,如果您使用的是 Laravel 的旧版本,您可能需要使用 composer update.

更新 Carbon