2016-06-03 7 views
0

Я такая ситуация, когда пользователи могут выбрать выставление счета каждый месяц, квартал или полугодие в одну конкретную дату, цикл выставления счетов. Я использую Laravel PHP framework.Php: Как я могу получить ту же дату следующих месяцев, ежеквартально и раз в полгода

Например. Ежемесячно - 5 мая 2016 года, 5 июня 2016 года, 5 июля 2016 года и т. Д. Выставляется по 5 на каждый месяц Например. Ежеквартально - 10 января 2016 года, 10 марта 2016 года, 10 июня 2016 года и т. Д. Выставляется по 10 каждые три месяца Например. Полу-Ежегодно - 13 апреля 2016, 13 сентября 016 Выставляется по 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); 
    } 

} 

Это моя функция, которую я хотел генерирует даты по дате пользователя выбора, основанного на полугодовой, квартальной и месячной оплаты разрыв.

+1

Добро пожаловать на SO, пожалуйста, напишите код .. я имею в виду попытаться найти решение и только потом спросить .. это выглядит как «дать мне решение» вид вопроса которого никто здесь не любит :) – nayana

+0

Извините. У меня не было никакой идеи или кода при публикации этого вопроса, у меня была единственная пустая функция, поэтому я думал, что это никому не поможет. @otopolsky –

+0

hm у вас есть множество ответов, так что это может быть хорошим вопросом в конце концов :) Я имел в виду, что когда вы показываете какой-то код .. или, по крайней мере, «псевдокод» того, что вы хотите достичь, это поможет людям понять, что вы хочу достичь .. и в то же время вы можете найти какое-то решение, попробовав что-то .. мне это случалось несколько раз, когда я задавал вопрос .. тогда я, хотя нормально, добавил код ... и я написал немного что-то - И это сработало! есть хороший день .. – nayana

ответ

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';.

+0

Если кто-то выбирает 31 января? https://eval.in/582429 – Andreas

+0

уже сказал, что ему нужно подумать об этом, он не даст такой же даты. Его словесно неправильно, если мы говорим «то же, что и в следующем месяце», нет? – C2486

+0

Извините, я не читал это предложение. Да, возможно, в следующем месяце, возможно, будет указано одно и то же число суток. – Andreas

1

Я не совсем уверен, что вы ищете, но я думаю, что следующее поможет вам на вашем пути.

Вы можете использовать DateTime и DateInterval, чтобы манипулировать датами для добавления в течение нескольких месяцев.

// 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 
0

на основе кода из Риши я сделал это.
Он разделяет дату на две части и использует расчеты один на месяц, а другой - на день.

Редактировать: заметили довольно очевидную ошибку в коде.

<?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 
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 

Quarterly (за четыре квартала)

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

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