PHP: Как заполнить массив датами (Ymd) в качестве ключей

0

Я хочу заполнить массив значениями. Ключи этого массива должны быть читаемыми датами в формате "YEAR-MONTH-DAY". Отправной точкой является "2010-5-25". Процесс должен прервать текущую дату. Очевидно, что все даты должны быть действительными.

Я думал об этом цикле. Но, похоже, PHP не может проверить состояние более одного в цикле "for". Однако он не дает мне никаких предупреждений или ошибок.

    for ($d = 25, $m = 5, $y = 2010,
        $this_day = date('j'),
        $this_month = date('n'),
        $this_year = date('Y');
        ($y <= $this_year) && ($m <= $this_month) && ($d <= $this_day);
        $d++)
    {
            $values[$y.'-'.$m.'-'.$d] = 0; //fill array
            $d++;
            if(!checkdate($m, $d, $y)){
                $d = 1;
                $m++;
                if($m > 12) { $m = 1; $y++; }
        }
    }

Выполнение этого с вложенными петлями было бы довольно болезненным.

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

Есть ли более эффективный способ?

Теги:
arrays
date

5 ответов

2

Просто вы можете попробовать использовать strtotime(). Пример:

$values = array();
$oldDate = strtotime('2010-05-25');
while($oldDate <= time()){
    $values[date('Y-m-d', $oldDate)] = 'Your value';
    $oldDate += 86400;
    //Other codes
}
  • 1
    Это должно быть 86400, а не 86000. Кроме того, если вы хотите, чтобы даты соответствовали дате, но не включали сегодняшнюю дату, изменение $oldDate <= time() на $oldDate < time() НЕ будет работать.
  • 0
    Спасибо @TomRobinson, это была опечатка :) +1
1

Вот код, который выполняет некоторую проверку ошибок, например, допустимые даты и дата начала не могут быть больше даты окончания:

function arrayKeyDates($start, $end='now') {
    // can use DateTime::createFromFormat() instead
    $startDate = new DateTime($start);
    $endDate = new DateTime($end);

    if ($startDate === false) {
        // invalid start date.
        return;
    }

    if ($endDate === false) {
        // invalid end date.
        return;
    }

    if ($startDate > $endDate) {
        // start date cannot be greater than end date.
        return;
    }

    $dates = array();
    while($startDate <= $endDate) {
        $dates[$startDate->format('Y-n-j')] = 0;
        $startDate->modify('+1 day');
    }

    return $dates;
}

print_r(arrayKeyDate('2014-11-30'));

Я получаю следующий вывод:

Array
(
    [2014-11-30] => 0
    [2014-12-1] => 0
    [2014-12-2] => 0
    [2014-12-3] => 0
    [2014-12-4] => 0
    [2014-12-5] => 0
    [2014-12-6] => 0
    [2014-12-7] => 0
)

Код обработки ошибок предоставляется вам.

UPDATE (DateTime :: createFromFormat) Если вы хотите создать объекты DateTime с использованием настраиваемого формата, вы можете в моей функции сделать что-то вроде этого:

$startDate = DateTime::createFromFormat('Y-n-j', $start);

Где $start будет иметь значение 2010-5-25.

Для получения дополнительной информации см.: http://php.net/manual/en/datetime.createfromformat.php

0

Прежде всего; цикл не выполняется, потому что вы проверяете отдельно, если номер года меньше, чем номер текущего года и т.д. Но сегодня это седьмое, и вы начинаете с 25 мая 2010 года:

$d = 25;
$this_day = date('j'); // today: 7
$loop = $d <= $this_day; // evaluates to false

Поскольку "дневная проверка" оценивается как false, все выражение оценивается как false. Таким образом, цикл начнет работать только 25 декабря.

Вы можете лучше использовать объект DateTime для построения дат и выполнения модификаций созданного объекта. Это также обеспечит вам много пота с такими вещами, как високосные годы и т.д. Пример:

for ( 
        $start = new DateTime('2010-05-25'), 
            $today = new DateTime('now') ;
        $start->diff($today)->format('%a') >= 0 ;
        $start->modify('+1 day')
) {
    $values[$start->format('Y-m-d')] = 0;
}

легко!

0

Я взял на себя смелость немного очистить свой код, чтобы сделать его доступным для чтения:

<?php

$this_day = date('j');
$this_month = date('n');
$this_year = date('Y');
echo sprintf("Today: d-m-y: %s-%s-%s\n", $this_day, $this_month, $this_year);

for ($d = 25,  $m = 5,  $y = 2010;
    ($y <= $this_year) && ($m <= $this_month) && ($d <= $this_day);
    $d++) {
        echo sprintf("Date: d-m-y: %s-%s-%s\n", $d, $m, $y);
        $values[$y.'-'.$m.'-'.$d] = 0; //fill array
        $d++;
        if(!checkdate($m, $d, $y)){
            $d = 1;
            $m++;
            if($m > 12) { $m = 1; $y++; }
     }
}

Это показывает, что код работает отлично. То есть, если вы выбрали правильное условие! Сегодня 07-го, но ваши начальные значения начинаются с 25-го, что фальсифицирует условие. Чтобы проверить выбранный день начала "02" и увидеть результат...

Я думаю, вы хотите пересмотреть свое состояние. Скорее всего, это то, что вы хотите выразить...

0
$startDate = new \DateTime('2010-05-25');
$endDate = new \DateTime();

$interval = new \DateInterval('P1D');
$period = new \DatePeriod ($startDate, $interval, $endDate);

$dates = array();
foreach ($period as $key => $date) {
    $dates[$date->format('Y-m-d')] = null;
}
var_dump($dates);

Ещё вопросы

Сообщество Overcoder
Наверх
Меню