Сбор информации между 2 датами в php

#php

#php

Вопрос:

У меня есть массив, который выглядит примерно так

 $data =
        [
            [
                'date' => '2020-10-01',
                'product' => 'Product 1',
                'description' => 'Product 1',
            ],
            [
                'date' => '2020-11-01',
                'product' => 'Product 2',
                'description' => 'Product 2',
            ],
            [
                'date' => '2020-12-01',
                'product' => 'Product 3',
                'description' => 'Product 3',
            ],
            [
                'date' => '2021-01-01',
                'product' => 'Product 4',
                'description' => 'Product 4',
            ]
        ];
 

И то, что я хотел бы сделать, это получить всю информацию между 2 датами.
Например, я хочу, чтобы все было между 2021-01-01 и 2020-11-01, и тогда он отобразил бы продукт 2, продукт 3 и продукт 4

Я не уверен, как поступить с этим

Комментарии:

1. Вы пишете цикл, внутри него вы проверяете даты и т. Д. И т. Д.

2. Что вы подразумеваете под «между 2 датами»? Вы хотите посмотреть на фактические даты, поэтому, если запись содержит дату между вашими двумя датами, ее следует использовать, или вы смотрите только на массив и используете только записи, которые находятся между двумя выбранными записями массива? Отсортирован ли массив?

3. И если эти данные поступают из базы данных, самым простым решением может быть изменение запроса в соответствии с вашими требованиями

Ответ №1:

 <?php
$data =
        [
            [
                'date' => '2020-10-01',
                'product' => 'Product 1',
                'description' => 'Product 1',
            ],
            [
                'date' => '2020-11-01',
                'product' => 'Product 2',
                'description' => 'Product 2',
            ],
            [
                'date' => '2020-12-01',
                'product' => 'Product 3',
                'description' => 'Product 3',
            ],
            [
                'date' => '2021-01-01',
                'product' => 'Product 4',
                'description' => 'Product 4',
            ]
        ];
        
$from = new DateTime('2020-11-11');
$to = new DateTime('2030-10-13');
        
foreach ($data as $d){
    $productDate = new DateTime($d['date']);
    if (($productDate >= $from) amp;amp; ($productDate <= $to)){
        echo "is between";
        var_dump($d);
    }
        
}
 

Комментарии:

1. Да, я не понял, что вы по какой-то причине изменили начальную и конечную даты по сравнению с теми, которые использовались в вопросе 🙂

Ответ №2:

В случае, если вы хотите сделать это в PHP, вы можете создать аналогичную функцию для SQL WHERE … BETWEEN … И … с помощью array_filter.

Если у вас есть доступ к SQL-запросу, то, вероятно, вы хотите, чтобы об этом позаботилась СУБД, как упоминал @RiggsFolly в комментариях.

 $lowerBound = strtotime('2020-11-01');
$upperBound = strtotime('2021-01-01');

$result = array_filter($data, function ($item) use ($lowerBound, $upperBound) {
    $itemDate = strtotime($item['date']); 

    return $lowerBound <= $itemDate amp;amp; $itemDate <= $upperBound;
});

echo '<pre>';
print_r($result);
echo '</pre>';
 

Комментарии:

1. Надеюсь, вы не возражаете, просто подумал, что я бы сэкономил несколько циклов процессора

Ответ №3:

Согласно комментариям, если данные изначально получены из запроса к базе данных, гораздо лучше ограничить их содержимое, например:

 // SQL query to be used in a prepared statement

SELECT date, product, description
FROM products 
WHERE date >= ?
    AND date <= ?
 

Однако, в противном случае ключевым моментом здесь является то, что все даты правильно отформатированы: timetamps следуйте шаблону Y-m-d , что означает, что хронологический и алфавитный порядок одинаковы

 Generally...
    Start        ===>   End
    A            ===>   Z
    1            ===>   10
    0000-00-00   ===>   9999-99-99

Which means...
    2020-12-30 < 2020-12-31 < 2021-01-01
 

В этом случае, когда мы сравниваем две правильно отформатированные даты (в том же формате), нам не нужно изменять тип / формат данных; преобразование строки в DateTime or strtotime ничего не добавляет, кроме ~10x требуемого времени, по сравнению со сравнением значений в строковом формате.

В любом случае, сравнивая даты:

Использование array_filter

 $minDate = '2020-11-01';
$maxDate = '2021-01-01';
$result  = array_filter($data, function ($item) use ($minDate, $maxDate) {
    return $minDate <= $item["date"] amp;amp; $item["date"] <= $maxDate;
});
 

Использование foreach

 $minDate = '2020-11-01';
$maxDate = '2021-01-01';
$result  = [];

foreach($data as $item){
    if($minDate <= $item["date"] amp;amp; $item["date"] <= $maxDate){
        $result[] = $item;
    }
}