Как искать диапазон файлов, используя даты в php?

Я пытаюсь сделать инструмент поиска файлов php, который использует диапазон дат, полученных из формы.
У меня есть каталоги, которые имеют следующий шаблон. Есть тысячи файлов, но это только пример.

ежедневная папка

 chl-2009-05-08-121000.L2_LAC.x.png
chl-2009-05-09-111500.L2_LAC.x.png
chl-2009-05-09-112000.L2_LAC.x.png etc

еженедельная папка

lst-2014-W36.png
lst-2014-W37.png
lst-2014-W39.png etc

Форма имеет поле параметра, которое получит chl, lst и другие. Другие поля взяты из поля ввода даты, недели и т. Д.

Так что я хочу достичь, например, найти все файлы с именами файлов в диапазоне от 2002-04-14 а также 2003-05-25, У меня есть переменная, которая предоставляет дату.

То, что я делал до сих пор, перечисляет только файлы, которые точно соответствуют предоставленным значениям с подстановочными знаками, но я не смог получить все файлы в пределах диапазонов дат. Я попытался для ежедневной папки.

$a = glob($datadir."{". $_GET['parameter'] .'-'.  $_GET["date"]. "*,". $_GET['parameter'] .'-'.  $_GET["date2"]. "*}" , GLOB_BRACE);
foreach($a as $image)
{
echo "<a href='".$image."'>" . basename($image) . "</a><br />";
}

Причина, по которой я использовал здесь символы подстановки, состоит в том, чтобы избежать проверки значений, подобных этим 112000.L2_LAC.x.png.

Спасибо!

0

Решение

Хитрость заключается в преобразовании ваших имен файлов и полей $ _POST в фактические даты, а затем в сравнение. Слишком проблематично рассматривать их как числа или строки & регулярные выражения.

Этот код заботится о chl случай и lst дело. Вы можете использовать ту же технику, чтобы обратиться к другим. Имейте в виду, что $user_start_date а также $user_end_date даты PHP Не струны.

Внизу я жестко запрограммировал некоторые даты начала и окончания. Очевидно, вы бы вместо этого использовали ваши значения $ _GET [‘date’] и $ _GET [‘date2’]. Документы PHP для DateTime :: createFromFormat () содержит информацию о том, как преобразовать строки различного формата в даты.

function filesInRange($datadir, $parameter, $user_start_date, $user_end_date) {

$all_files  = array();
$good_files = array();

//  first create an array of all the filenames, to keep I/O to a minimum
foreach (new DirectoryIterator($datadir) as $fileInfo) {
if ( $fileInfo->isFile() ) {
$all_files[] = $fileInfo->getFileName();
}
}

switch ($parameter) {

case 'chl':
foreach ($all_files as $filename) {
//  we only operate on filenames that start with "chl". we skip others
if ( strpos($filename, $parameter) === 0 ) {
$pattern = '/(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})-(?<hour>\d{2})(?<minute>\d{2})(?<second>\d{2})/';
preg_match($pattern, $filename, $matches);
$filedate = DateTime::createFromFormat('Y-m-j-His',$matches[0]);
//  check range
if ($filedate >= $user_start_date && $filedate <= $user_end_date) {
$good_files[ $filedate->getTimestamp() ] = $filename;
}
}
}
break;

case 'lst':
foreach ($all_files as $filename) {
if ( strpos($filename, $parameter) === 0 ) {
$pattern = '/(?<year>\d{4})-W(?<week>\d{1,2})/';
preg_match($pattern, $filename, $matches);
//  start on Jan 1 and keep adding days until we reach our desired week
$file_start_date = DateTime::createFromFormat('Y-m-d G:i:s',$matches['year'].'-01-01 00:00:00');
while ( $file_start_date->format('W') < $matches['week'] ) {
$file_start_date->modify('+1 day');
}
//  add one week to get the end date
//  the start day starts on the very first second of the day (00:00:00)
//  the end date ends on the last second (23:59:59)
$file_end_date = clone $file_start_date;
$file_end_date->modify('+8 day');
$file_end_date->modify('-1 second');

//  check range
if ($file_start_date >= $user_start_date && $file_end_date <= $user_end_date) {
$good_files[ $file_start_date->getTimestamp() ] = $filename;
}
}
}
break;

case 'some_other_format':
//  handle other formats
break;

}
return $good_files;
}

$start = DateTime::createFromFormat('Y-m-j-His','2013-08-01-121000');
$end   = DateTime::createFromFormat('Y-m-j-His','2015-09-15-121000');

$result1 = filesInRange($datadir, 'lst', $start, $end );

var_dump($result1);
1

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

Наконец работает диапазон поиска по всем форматам даты.

Этот код ниже взят из оригинального поста sean9999. Это работает для даты (ГГГГ-ММ-ДД), месяца (ГГГГ-ММ) и сезонного = ежемесячно (ГГГГ-январь).

function filesInRange($datadir, $timeper1, $timeper2, $format, $patternval) {
$matches=array();
$good_files = array();
$start = DateTime::createFromFormat( $format,$timeper1);
$end   = DateTime::createFromFormat( $format,$timeper2);
$matches=array();

foreach (new DirectoryIterator($datadir) as $fileInfo) {

if ( !$fileInfo->isDot() && $fileInfo->isFile() ) {
//  create a date by parsing the file name
//$pattern = $patternval ;
preg_match($patternval, $fileInfo->getFileName(), $matches);
if ($matches) {
$filedate = DateTime::createFromFormat($format, $matches[0]);
}//  determine if it's between start and end date
if ($filedate >= $start && $filedate <= $end) {
$good_files[] = $datadir.$fileInfo->getFileName();
}
}
}

asort($good_files);
return $good_files;
}

Для вызова функции для ежедневных файлов.

$allfiles=filesInRange( "data/". $_GET["parameter"] . "/daily/", $_GET['date'], $_GET['date2'], 'Y-m-j', '/(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/');

К сожалению, DateTime::createFromFormat не поддерживает формат недели, как 2001W52 или же 2001-W52, Таким образом, мне пришлось искать другой путь. Так что с незначительными изменениями я использовал date() функция. Вот код для еженедельного поиска файлов.

function filesInRangeweek($datadir, $timeper1, $timeper2, $format, $patternval) {
$matches=array();
$good_files = array();
$start = date($format, strtotime($timeper1));
$end   = date($format, strtotime($timeper2));
$matches=array();

foreach (new DirectoryIterator($datadir) as $fileInfo) {

if ( !$fileInfo->isDot() && $fileInfo->isFile() ) {
//  create a date by parsing the file name
//$pattern = $patternval ;
preg_match($patternval, $fileInfo->getFileName(), $matches);
if ($matches) {
//echo $matches[0];
$filedate =date($format, strtotime($matches[0]));
}//  determine if it's between start and end date
if ($filedate >= $start && $filedate <= $end) {
$good_files[] = $datadir.$fileInfo->getFileName();
}
}
}

asort($good_files);
return $good_files;
}

Вызвать функцию;

$result=filesInRangeweek( "data/lst/weekly/", '2013-W35', '2013-W45',"oW", '/(?<year>\d{4})-W(?<week>\d{2})/');
1

По вопросам рекламы [email protected]