Как рассчитать цикл выставления счетов по заданной дате в PHP?

Я хочу получить результат, как показано ниже.

Исходная точка дня выставления счета: 21

Обычный расчетный период — с 2015-01-21 до 2015-02-20, 2015-02-21 до 2015-03-20, 2015-03-21 до 2015-04-20, … … …

За Первый месяц составить расчетный период.

Когда дата начала регистрации клиента (2015-01-13) и дата окончания (2015-05-10) раньше, чем 2015-01-21 (расчетный день 21),
Я хочу сделать период с 2015-01-13 по 2015-01-20.

но если дата начала регистрации клиента (2015-01-25) и дата окончания (2015-05-25) после 2015-01-21, я хочу сделать период с 2015-01-25 по 2015-02-20.

За последний месяц

Когда клиент завершить регистрацию 2015-05-10 до дня выставления счета (2015-05-21), я хочу сделать период с 2015-04-21 по 2015-05-10.

Когда клиент завершить регистрацию 2015-05-25 после дня выставления счета (2015-05-21), я хочу сделать период с 2015-05-21 по 2015-05-25.

ex1) Заданная дата начала: 2015-01-10, Заданная дата окончания: 2015-03-19

Результат:

$array[0]['start'] = 2015-01-10;
$array[0]['end'] = 2015-01-20;
$array[1]['start'] = 2015-01-21;
$array[1]['end'] = 2015-02-20;
$array[2]['start'] = 2015-02-21;
$array[2]['end'] = 2015-03-19;

пример 2) Заданная дата начала: 2015-01-24, Заданная дата окончания: 2015-03-25

Расчетный день: 21

Результат:

$array[0]['start'] = 2015-01-24;
$array[0]['end'] = 2015-02-20;
$array[1]['start'] = 2015-02-21;
$array[1]['end'] = 2015-03-20;
$array[2]['start'] = 2015-03-21;
$array[2]['end'] = 2015-03-25;

ex3) Заданная дата начала: 2015-01-24, Заданная дата окончания: 2015-04-18

Расчетный день: 21

Результат:

$array[0]['start'] = 2015-01-24;
$array[0]['end'] = 2015-02-20;
$array[1]['start'] = 2015-02-21;
$array[1]['end'] = 2015-03-20;
$array[2]['start'] = 2015-03-21;
$array[2]['end'] = 2015-04-18;

Я сделал функцию, как показано ниже, но эта функция имеет проблему в прошлом месяце.

function dateRange($firstDate, $lastDate, $step = '+1 day', $format = 'Y-m-d', $period='21' ){
$dates = array();

$first  = strtotime($firstDate);
$current= strtotime($firstDate);
$last   = strtotime($lastDate);

$startSet = $period;
$endSet = $period - 1;

$startFormat = "Y-m-{$startSet}";
$endFormat = "Y-m-{$endSet}";

$startMonth = date("Y-m", $first);
$endMonth = date("Y-m", $last);

$i=0;

while( $current <= $last ){

if($first==$current){
// first month

$dates[$i]['start'] = $firstDate;

$chkStartDay = date("d", $first);
if($chkStartDay < $period){

// end period of first month.
$dates[$i]['end'] = date($endFormat, $current);

// if start date is bigger than 21 period, add array
$i++;

$dates[$i]['start'] = date($startFormat, $current);
$dates[$i]['end'] = date($endFormat, strtotime("+1 month", $current));}else{
$dates[$i]['end'] = date($endFormat, strtotime("+1 month", $current));
}

}else{

$dates[$i]['start'] = date($startFormat, $current);
$dates[$i]['end'] = date($endFormat, strtotime("+1 month", $current));;}

$current = strtotime($step, $current);

$i++;
}return $dates;
}

$dates = dateRange('2015-01-12', '2015-05-23', "+1 month", "Y-m-d", '21');//increase by one month

Спасибо

-3

Решение

Ты можешь использовать DateTime за это

как это:

$startDateString = '2015-01-10';
$startDate = new DateTime($startDateString);
$newDate = $startDate->add(new DateInterval('P1D')); // P1D adds one day

Вы могли бы создать for цикл для создания желаемого массива в качестве результата.
Увидеть документы на DateInterval для получения дополнительной информации.

Удачи!

0

Другие решения

Я просто изменил свою функцию, как показано ниже, и она работает, если кто-то знает лучший код, пожалуйста, дайте мне знать.

function dateRange($firstDate, $lastDate, $step = '+1 day', $format = 'Y-m-d', $period='21' ){
$dates = array();

$first  = strtotime($firstDate);
$current= strtotime($firstDate);
$last   = strtotime($lastDate);

$startSet = $period;
$endSet = $period - 1;

$startFormat = "Y-m-{$startSet}";
$endFormat = "Y-m-{$endSet}";$i=0;
$loopEnd = true;
while( $current <= $last ){

if($first==$current){
//Start Month

$dates[$i]['startDate'] = $firstDate;

$chkStartDay = date("d", $first);
if($chkStartDay < $period){$dates[$i]['endDate'] = date($endFormat, $current);

}else{
$dates[$i]['endDate'] = date($endFormat, strtotime("+1 month", $current));
}

$nextDateEnd = $dates[$i]['endDate'];

}else{$dates[$i]['startDate'] = date("Y-m-d", strtotime("+1 day", strtotime($nextDateEnd)));
$dates[$i]['endDate'] = date($endFormat, strtotime("+1 month", strtotime($dates[$i]['startDate'])));;if($lastDate < $dates[$i]['endDate']){
$dates[$i]['endDate'] = $lastDate;
$loopEnd = false;
}

}

$nextDateStart = $dates[$i]['startDate'];
$nextDateEnd = $dates[$i]['endDate'];

$current = strtotime($step, $current);

$i++;
}if($lastDate > date($endFormat, strtotime($lastDate)) and $loopEnd == true ){
$i++;

$dates[$i]['startDate'] = date("Y-m-d", strtotime("+1 day", strtotime($nextDateEnd)));
$dates[$i]['endDate'] = $lastDate;}

return $dates;
}

$dates = dateRange('2015-01-11', '2015-05-27', "+1 month", "Y-m-d", '21');//increase by one month

результат:

Array
(
[0] => Array
(
[start] => 2015-01-10
[end] => 2015-01-20
)

[1] => Array
(
[start] => 2015-01-21
[end] => 2015-02-20
)

[2] => Array
(
[start] => 2015-02-21
[end] => 2015-03-20
)

[3] => Array
(
[start] => 2015-03-21
[end] => 2015-04-20
)

[4] => Array
(
[start] => 2015-04-21
[end] => 2015-05-11
)

)

0