Php:我如何在接下来的几个月,每季度和每半年获得相同的日期

时间:2016-06-03 09:26:20

标签: php laravel datetime php-carbon

在这种情况下,用户可以选择在结算周期中选择的特定日期每月,每季度或每半年收费。我正在使用Laravel PHP框架。

EG。每月 - 2016年5月5日,2016年6月5日,2016年7月5日等 每月5点结算 例如。每季度 - 2016年1月10日,2016年3月10日,2016年6月10日等... 每三个月收费10 例如。半年 - 2016年4月13日,016年9月13日 每六个月收费13次。

这里的目标是在用户选择开帐单的每个月获得相同的日期,但是在一个月,每季度或每半年。

这是我用@Rishi方法玩了一段时间后的代码

public function as_you_go($pay_as_you_go,$grand_total,$payment_date,$policy_id)
{
    $policy = $this->findorFail($policy_id);
    if($pay_as_you_go == 'Semi-Annually'){
        $payments_no = 2;
        $installment_amount = $grand_total/$payments_no;
        $month_gap = 6;
        $add_month = '+6 month';
    }elseif($pay_as_you_go == 'Quarterly'){
        $payments_no = 4;
        $installment_amount = $grand_total/$payments_no;
        $month_gap = 3;
        $add_month = '+3 month';
    }elseif($pay_as_you_go == 'Monthly'){
        $payments_no = 12;
        $installment_amount = $grand_total/$payments_no;
        $month_gap = 1;
        $add_month = '+1 month';
    }

    // Pay as you go calculations
    for ($x = 0; $x < $payments_no; $x++) {
        //$add_month = '+'.$x.' month';
        $installment = new \App\Installment;
        $installment->amount = $installment_amount;


        if(\App\Installment::wherePayableType('App\Policy')->wherePayableId($policy->id)->first()){

            $payment = \App\Installment::wherePayableType('App\Policy')->wherePayableId($policy->id)->orderBy('id', 'desc')->first();
            $date = $payment->payment_date->format('Y-m-d');
            $installment->payment_date = date('Y-m-d',strtotime($date.$add_month));
        }else{
            $installment->payment_date = $payment_date;
        }
        $installment->is_payed = 'No';
        $policy->installments()->save($installment);
    }

}

这是我的功能,我希望根据用户的半年度,季度和月度支付差距,根据用户的日期生成日期。

4 个答案:

答案 0 :(得分:2)

试试这个

<?php
  $date = '1-may-2016';
  echo date('d-F-Y',strtotime($date.'+1 month'))."\n";
  echo date('d-F-Y',strtotime($date.'+3 month'))."\n";
  echo date('d-F-Y',strtotime($date.'+6 month'))."\n";
?>

在此检查输出:https://eval.in/582424

此外,您还需要考虑$date = '30-jan-2016';等日期。

答案 1 :(得分:1)

我不完全确定您要找的是什么,但我认为以下内容可以帮助您。

您可以使用DateTimeDateInterval来操作日期,以便在几个月内添加。

// We have a DateTime object which is on the 5th may
$date = new DateTime('2016-05-05');

$billingType = 'monthly';

switch ($billingType) {
    case 'monthly':
        $interval = new DateInterval('P1M');
        break;

    case 'quarterly':
        $interval = new DateInterval('P3M');
        break;

    case 'biannually':
        $interval = new DateInterval('P6M');
        break;
}

$newDate = clone $date;
$newDate->add($interval);

echo $date->format('Y-m-d'); // 2016-05-05
echo $newDate->format('Y-m-d'); // 2016-06-05

让我们说你想检查今天是否是向某人收费的日子......

function isBillingDate(DateTime $date, DateTime $billingDate, $billingType)
{
    switch ($billingType) {
        case 'monthly':
            $interval = new DateInterval('P1M');
            break;

        case 'quarterly':
            $interval = new DateInterval('P3M');
            break;

        case 'biannually':
            $interval = new DateInterval('P6M');
            break;
    }

    $isBillingDate = false;

    $date->setTime(00, 00, 00);
    $billingDate->setTime(00, 00, 00);

    do {
        if ($date == $billingDate) {
            $isBillingDate = true;
        } else {
            $billingDate->add($interval);
        }
    } while ($isBillingDate === false && $date <= $billingDate);

    return $isBillingDate;
}

$date = new DateTime('now'); // We want to check if we should bill them today (3rd June)

$billingStartDate = new DateTime('2016-05-03'); // They signed up to get billed on the 3rd of May
$billingType = 'monthly'; // They want to get billed every month
var_dump(isBillingDate($date, $billingStartDate, $billingType)); // True

$billingStartDate = new DateTime('2016-03-03'); // They signed up to get billed on the 3rd of March
$billingType = 'quarterly'; // They want to get billed quarterly
var_dump(isBillingDate($date, $billingStartDate, $billingType)); // True

$billingStartDate = new DateTime('2016-04-03'); // They signed up to get billed on the 3rd of April
$billingType = 'quarterly'; // They want to get billed quarterly
var_dump(isBillingDate($date, $billingStartDate, $billingType)); // False

答案 2 :(得分:0)

根据Rishi的代码我做了这个。
它将日期分为两部分,并使用一个月计算,另一个计算到当天。

编辑:发现代码中有一个非常明显的错误。

<?php
$date = '2016-01-26';
$date2= substr($date,0,7)."-01";
$period = "+3 month";

If(substr($date,-2) >  date('t',strtotime($date2.$period))){

    echo date('t-F-Y',strtotime($date2.$period))."\n";

}else{

    echo date("d-", strtotime($date)) . date('F-Y',strtotime($date2.$period))."\n";

}
?>

https://eval.in/582564

输出:

From 31 of january:
28-February-2016
30-April-2016
31-July-2016

答案 3 :(得分:0)

function iterateMonths(DateTime $date, $months = 1, $iterations = 12)
{
    $day = $date->format('d');

    for ($a = 0; $a < $iterations; $a++)
    {
        // Increment at least one month, but cap at the last day
        $date->modify("last day of next month");

        // Add on additional months if required
        if ($months > 1)
        {
            $mDiff = $months-1;
            $date->modify("+{$mDiff} months");
        }

        // If we are billing earlier than the last day of the month,
        // rewind that number of days
        if ($day < $date->format('d'))
        {
            $dDiff = $date->format('d') - $day;
            $date->modify("-{$dDiff} days");
        }

        echo $date->format('Y-m-d'), PHP_EOL;
    }
}

标准月度结算

$date = new \DateTime('2016-06-03');
iterateMonths($date);
// 2016-07-03, 2016-08-03, 2016-09-03, etc

几个月的晚数

$date = new \DateTime('2016-01-31');
iterateMonths($date, 1, 11);
// 2016-02-29, 2016-03-31, 2016-04-30, 2016-05-31

每季度(四季度)

$date = new \DateTime('2016-07-14');
iterateMonths($date, 3, 4);

// 2016-10-14, 2017-01-14, 2017-04-14, 2017-07-14