【问题标题】:Php: How can I get the same date of the following months, quarterly and semi-annuallyPhp:如何获得下个月,每季度和每半年的相同日期
【发布时间】:2016-06-03 09:26:20
【问题描述】:

在这种情况下,用户可以选择每月、每季度或每半年在一个特定日期进行计费,以选择计费周期。我正在使用 Laravel PHP 框架。

例如。每月 - 2016 年 5 月 5 日、2016 年 6 月 5 日、2016 年 7 月 5 日等。 每个月 5 点结算 例如。季度 - 2016 年 1 月 10 日、2016 年 3 月 10 日、2016 年 6 月 10 日等... 每三个月后 10 点结算 例如。半年 - 2016 年 4 月 13 日,2016 年 9 月 13 日 每六个月后在 13 号结算。

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

这是我使用@Rishi methode 一段时间后的代码

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);
    }

}

这是我的功能,我想根据用户选择的日期根据半年、季度和每月的付款差距生成日期。

【问题讨论】:

  • 欢迎来到 SO,请发布一些代码.. 我的意思是尝试找到解决方案,然后才问.. 这看起来像“给我解决方案”之类的问题,这里没有人喜欢 :)
  • 对不起..发布这个问题时我没有任何想法或代码,我只有一个空白函数,所以我认为它不会帮助任何人。 @otopolsky
  • hm 你得到了足够多的答案,所以这毕竟是一个好问题 :) 我的意思是当你展示一些代码时......或者至少你想要实现的“伪代码”会有所帮助人们了解您想要实现的目标..同时您可能会通过尝试找到一些解决方案..当我问问题时,我遇到过几次..然后我虽然可以让我们添加一些代码..和我只写了一点东西——它奏效了!祝你有美好的一天..

标签: php laravel datetime php-carbon


【解决方案1】:

这样试试

<?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'; 这样的日期。

【讨论】:

  • 已经说过他需要考虑一下,它不会给出相同的日期。如果我们说same date for next month 不是,那它在口头上是错误的?
  • 很抱歉没有以那种方式阅读那句话。是的,它也许应该说下个月的同一天数。
  • 一种尝试过的方法 Rishi 进行了一些更新,效果很好。谢谢大家的支持。
  • @MichaelReuben 我认为您应该发布代码。这是 SO 的一部分。答案是最重要的。其他人可能稍后会找到这个线程并想要代码。
  • 我在使用@Rishi 方法后添加了我的工作代码。
【解决方案2】:

我不完全确定您在寻找什么,但我认为以下内容会对您有所帮助。

您可以使用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

【讨论】:

    【解决方案3】:

    根据 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
    

    【讨论】:

      【解决方案4】:
      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
      

      【讨论】:

        猜你喜欢
        • 2018-10-19
        • 1970-01-01
        • 2021-10-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-12-08
        相关资源
        最近更新 更多