PHP функция для извлечения дней между двумя датами группы по годам - PullRequest
0 голосов
/ 27 ноября 2018

Мне нужна функция PHP, чтобы возвращать многомерный массив, чтобы иметь дни для каждого года между датами:

Es:

daysinyears('17-06-2012', '28-07-2018')

должен возвращать этот массив:

Array ( [0] => Array ([year] => 2018, [days] => 208),
        [1] => Array ([year] => 2017, [days] => 364),
        [2] => Array ([year] => 2016, [days] => 365),
        [3] => Array ([year] => 2015, [days] => 364),
        [4] => Array ([year] => 2014, [days] => 364),
        [5] => Array ([year] => 2013, [days] => 365),
        [6] => Array ([year] => 2012, [days] => 197)
      )

это то, что я сделал;

function daysinyears($d1, $d2) {
      // swap dates if wrong order
      if ($d1 > $d2) {
        $aux = $d1;
        $d1 = $d2;
        $d2 = $aux;
      }
      // if same year, just count days with date_diff
      if ($d1->format("Y") == $d2->format("Y")) {
        $days_year = array('year' => $d1->format("Y"), 
                             'days' => date_diff($d2, $d1)->format('%a'));
        $arr[] = $days_year;


      } else {
        $days_year = array('year' => $d2->format("Y"), 
                             'days' => date_diff($d2, date_create(date('d-m-Y',strtotime('01-01-'.$d2->format("Y")))))->format('%a'));
        $arr[] = $days_year;
        $year_prec = $d2->format("Y")-1;
        // Recursion
        $arr[] = daysinyears($d1, date_create(date('d-m-Y',strtotime('31-12-'.$year_prec))));
      }
      return $arr;
}

Это 'работает', но проблема в том, что рекурсия создает массив внутри другого, как это:

[0] => Array (
    [year] => 2018
    [days] => 208
    )
[1] => Array (
    [0] => Array (
        [year] => 2017
        [days] => 364
        )
    [1] => Array (
        [0] => Array (
            [year] => 2016
            [days] => 365
            )
        [1] => Array (
            [0] => Array (
                [year] => 2015
                [days] => 364
                )
            [1] => Array (
                [0] => Array (
                    [year] => 2014
                    [days] => 364
                    )
                [1] => Array (
                    [0] => Array (
                        [year] => 2013
                        [days] => 364
                        )
                    [1] => Array (
                        [0] => Array (
                            [year] => 2012
                            [days] => 197
                            )
                        )
                    )
                )
            )
        )
    )

Iне могу понять, как использовать рекурсию без возврата этих китайских ящиков.

Ответы [ 3 ]

0 голосов
/ 27 ноября 2018

Вместо добавления рекурсивного результата с $arr[] =, объедините его с $arr = array_merge($arr, ...):

$arr = array_merge($arr, daysinyears($d1, date_create(date('d-m-Y',strtotime('31-12-'.$year_prec)))));
0 голосов
/ 27 ноября 2018

Я думаю, что в ваших расчетах есть ошибка, поскольку общее количество дней в 2018 году должно быть 178 вместо 208. Я также думаю, что вы можете использовать более понятное решение, например:

function daysInYears($start, $end)
{
    $result = [];

    $start = new DateTime($start);
    $end = new DateTime($end);

    while ($start < $end) {

        $endOfYear = (clone $start)->modify('last day of december');

        if ($endOfYear > $end) {
            $endOfYear = $end;
        }

        $result[] = [
            'year' => $start->format('Y'),
            'days' => $endOfYear->diff($start)->days
        ];

        $start = $endOfYear->modify('+1 day');
    }

    return $result;
}

Результат daysInYears('17-06-2012', '28-06-2018') будет:

Array
(
    [0] => Array
        (
            [year] => 2012
            [days] => 197
        )

    [1] => Array
        (
            [year] => 2013
            [days] => 364
        )

    [2] => Array
        (
            [year] => 2014
            [days] => 364
        )

    [3] => Array
        (
            [year] => 2015
            [days] => 364
        )

    [4] => Array
        (
            [year] => 2016
            [days] => 365
        )

    [5] => Array
        (
            [year] => 2017
            [days] => 364
        )

    [6] => Array
        (
            [year] => 2018
            [days] => 178
        )

)
0 голосов
/ 27 ноября 2018

Вы можете решить эту проблему, передав sl в свой параметр.

function daysinyears($d1, $d2 , $sl) {
  // swap dates if wrong order
  if ($d1 > $d2) {
    $aux = $d1;
    $d1 = $d2;
    $d2 = $aux;
  }
  // if same year, just count days with date_diff
  if ($d1->format("Y") == $d2->format("Y")) {
    $days_year = array('year' => $d1->format("Y"), 
                         'days' => date_diff($d2, $d1)->format('%a'));
    $arr[$sl] = $days_year;


  } else {
    $days_year = array('year' => $d2->format("Y"), 
                         'days' => date_diff($d2, date_create(date('d-m-Y',strtotime('01-01-'.$d2->format("Y")))))->format('%a'));
    $arr[$sl] = $days_year;
    $year_prec = $d2->format("Y")-1;
    // Recursion
    $arr[$sl] = daysinyears($d1, date_create(date('d-m-Y',strtotime('31-12-'.$year_prec))),$sl++);
  }
  return $arr;


}

Установите параметр 0, где вы вызываете функцию

...