如何在php中使用日期搜索文件范围


How to search range of files using dates in 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-142003-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.这样的值

谢谢!

诀窍是将文件名和$_POST字段转换为实际日期,然后进行比较。把它们当作数字或字符串处理太有问题了;正则表达式。

此代码处理chllst的情况。你可以用同样的技巧来称呼别人。请记住,$user_start_date$user_end_date是PHP日期。不是字符串。

在底部,我硬编码了一些开始和结束日期。显然,您将使用$_GET[date']和$_GET[date2']值。DateTime::createFromFormat()的PHP文档包含如何将各种格式的字符串转换为日期的信息。

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);

最后,所有日期格式的范围搜索都开始工作了。

下面的代码来自sean9999的原始帖子。它适用于日期(YYYY-MM-DD)、月份(YYYY-MM)和季节=月份(YYYY-Jan)。

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不支持像2001W522001-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})/');