设置下个月的付款日期(使用PHP Carbon)

时间:2018-07-12 00:47:51

标签: php laravel php-carbon

我需要确定下个月的付款日期。所以我要到最后截止日期 并增加一个月的时间。我该怎么办?

我的例子是:上次付款是Januarry的31号,我在做

Carbon::create(2018, 1, 31, 0, 0, 0)->addMonthsNoOverflow(1)

并且有效,它给出2018-02-28,但是在那之后下一次付款将在28号再次发生。所以我需要在添加一个月后设置一个日期。

Carbon::create(2018, 2, 28, 0, 0, 0)->addMonthsNoOverflow(1)->day(31)

它给我2018-03-31很好,但是如果我在第一个示例中使用此公式

Carbon::create(2018, 1, 31, 0, 0, 0)->addMonthsNoOverflow(1)->day(31)

它给我溢出2018-03-03。这是我的问题。我该怎么办?是否有类似->setDayNoOverflow(31)的东西?

5 个答案:

答案 0 :(得分:4)

您不应使用上一个付款日期,而应保留第一个日期,并从第一个而不是前一个日期计算所有其他日期:

Carbon::create(2018, 1, 31, 0, 0, 0)
Carbon::create(2018, 1, 31, 0, 0, 0)->addMonthsNoOverflow(1)
Carbon::create(2018, 1, 31, 0, 0, 0)->addMonthsNoOverflow(2)
Carbon::create(2018, 1, 31, 0, 0, 0)->addMonthsNoOverflow(3)

假设您没有此数据,您仍然可以:

$day = 31;
$date = Carbon::create(2018, 1, 28, 0, 0, 0);
$date->addMonthsNoOverflow(1);
$date->day(min($day, $date->daysInMonth));

答案 1 :(得分:1)

似乎Carbon中没有这样的功能,那为什么不自己做呢?

public function setDaysNoOverflow($value)
    {
        $year = $this->year;
        $month = $this->month;

        $this->day((int)$value);

        if ($month !== $this->month) {
            $this->year = $year;
            $this->month = $month;
            $this->modify('last day of this month');
        }

        return $this;
    }

只需将其添加到Carbon/Carbon.php,它就可以完成工作。

它基于addMonthsNoOverflow函数源。

警告:未经测试,仅出于启发目的。

答案 2 :(得分:0)

我认为这里的实际问题是关于业务逻辑或数据库模式,而不是日期操纵。

尽管我不确定您的订阅模式是什么,但看来您想跟踪两个单独的信息:

  • 付费服务的日期,
  • 应在每月的第几天付款。

通过将它们都存储在一个字段中,您可能会丢失一些信息,就像一月/二月/三月过渡一样。通过使用单独的字段,您可以防止出现这种情况,并为每个月建立一个到期付款日期,例如KyleK提出的建议:

$lastPayment->addMonthsNoOverflow(1)->day(
    min($paymentDue->day, $lastPayment->daysInMonth)
);

我认为这是一种复杂的处理方式,可以通过以下方式大大简化:

  1. 使用工作月(30天)而不是日历月,
  2. 放开原始付款日,然后在最后一次付款后再增加一个月。

不过,我知道您可能无法决定。

答案 3 :(得分:0)

您可以将其用作循环

    // from month
    $min = 3;
    // to mont
    $max = 9;
    // all dates
    $paymentDates = [];
    $date2 = \Carbon\Carbon::now();
    // next day (or today)
    $day = $date2->addDay(1)->format('d');
    $currentMonth = $date2->format('m');
    $year = $date2->format('Y');;
    
    $date = \Carbon\Carbon::now();

    $nextMonth = $currentMonth;

    for($i = $min; $i <= $max; $i++) {
      $date = \Carbon\Carbon::create($year, $currentMonth, $day)->addMonthsNoOverflow($nextMonth)->format('d/m/Y');
      // add to array
      array_push($paymentDates, $date);
      // next month
      $nextMonth++;
    }

答案 4 :(得分:-1)

您可以使用Carbon库中可用的addMonth()函数,如下所示

jsonName := field.GetJsonName()