#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;
}
}