如何根据当前日期导入和打印CSV值


How import and print CSV values based on current date?

我有一个CSV文件,它是一个班次时间表,其中包含日期,时间和名称。任何想法我如何可以提取基于当前日期/时间的名称?CSV看起来像这样:

...
14 Oct 2015, 02, 12:00 - 18:00, 6, "", "John Doe", "Joe Smith"
14 Oct 2015, 03, 18:00 - 00:00, 6, "Jenny Roe", "", "Henry Smith"
15 Oct 2015, 01, 00:00 - 06:00, 6, "Jake Blake", "Bob Ford", ""
...

我需要的是运行代码并打印安排在下一个班次的人的名字,如:

Jenny Roe
Henry Smith

我知道我可以像这样将文件加载为数组:

<?php
$csv = array();
$lines = file('schedule.csv', FILE_IGNORE_NEW_LINES);
foreach ($lines as $key => $value)
{
    $csv[$key] = str_getcsv($value);
}
echo '<pre>';
print_r($csv);
?>

或者打印成文本:

<?php
$file = fopen("schedule.csv","r");
while(! feof($file))
  {
$line_of_text = fgets($file);
print $line_of_text . "<BR>";
  }
fclose($file);
?>

现在,我想知道从哪种方法开始会更好?如果有人能帮我解决这个问题,我保证我会最终学习PHP (doh!),并在某一天在这里发布回复作为证明。

谢谢你的帮助Osuwariboy!这感觉像是一场艰苦的斗争,但最终还是成功了。谢谢你。

我将试着用解决方案完整地描述这种情况:

我有schedule.csv文件格式如下(日期,未使用的数字,移位时间,移位长度,名称(最多6个):

...
01 Oct 2015 ,65 ,07:00 - 15:00 ,8 ,"","John Doe","Joe Smith","Martin Taylor","Henry Smith","Mike Miller"
01 Oct 2015 ,22 ,15:00 - 23:00 ,8 ,"","Bob Ford","Sarah Smith","Jack Williams","",""
01 Oct 2015 ,11 ,23:00 - 7:00 ,8 ,"","","Jenny Roe","Adam Davis","Jake Blake",""
02 Oct 2015 ,21 ,07:00 - 19:00 ,12 "Antonio Garcia","John Doe","Joe Smith","","Henry Smith","Mike Miller"
02 Oct 2015 ,22 ,19:00 - 07:00 ,12 ,"","Bob Ford","Sarah Smith","Jack Williams","",""
02 Oct 2015 ,11 ,07:00 - 15:00 ,8 ,"","","Jenny Roe","Adam Davis","Jake Blake",""
...

这里的主要问题是我正在寻找不是为当前安排的人,而是为下一个班次安排的人。轮班是8小时(常规)或12小时(周末一些随机的日子)。基于此,我不能简单地预测未来8或12小时,因为这会产生各种问题,如:

  • 在12h班次开始时展望8h(显示相同班次)

  • 在8小时轮班结束时展望12小时(跳过下一个)

轮班日期也有问题,例如:01 Oct 2015 23:00 - 7:00为10月1日开始,10月2日结束。

根据Osuwariboy的提示,我想出了以下解决方案:

<?php
date_default_timezone_set('Europe/Warsaw'); //we set the current timezone to match the time from our schedule
$currentDate = new DateTime();
$currentDateRegular = new DateTime(); //object with the time 8h ahead 
$currentDateWeekend = new DateTime(); //object with the time 12h ahead
$currentDateRegular->modify('+8 hours');
$currentDateWeekend->modify('+12 hours');
$file = fopen("schedule.csv","r");
$results = array();
$resultsFinal = array();
$resultsDiff = array();
$resultsDiffWeekend = array();
while (($data = fgetcsv($file, 0, ",")) !== FALSE)
{
    //we create an array that has four elements: the start time, the "-", the endtime 
    //of the shifts, and an empty one (not needed)
    $shiftTime = explode(" ", $data[2]);
    //we create an object with a shift date
    $shiftDate = $data[0];
    //we create an object with a shift lenght time (8 or 12 hours)
    $shiftDiff = $data[3];
    //we create an object with a shift start time *including* date
    $startShift = dateTime::createFromFormat("d M Y H:i", $data[0] . " " . $shiftTime[0]);
    //we create same object as above to modify it with the shift lenght time
    $startShiftTemp = dateTime::createFromFormat("d M Y H:i", $data[0] . " " . $shiftTime[0]);
    //we create an oject with a shift end time *including* date - that may be different
    //from the start time eg. 23:00 - 7:00 (next day)
    $endShift = $startShiftTemp->modify('+' . $shiftDiff . " " . 'hours');

    //we compare the previously created objects three times: to the current date, date 8h ahead and 12h
    //ahead, then if the current date is between the start of the shift and the end of the shift,  
    //we know who is scheduled to work
    if($currentDate >= $startShift && $currentDate <= $endShift) {
    $results = $data;
    }
    if($currentDateRegular >= $startShift && $currentDateRegular <= $endShift) {
    $resultsDiff = $data;
    }
    if($currentDateWeekend >= $startShift && $currentDateWeekend <= $endShift) {
    $resultsDiffWeekend = $data;
    }
    //the most important part here: if the results for the current date are equal with the results for the 
    //date with the time 8h ahead (not what we want), that means that the final results should be with the 
    //names for the date 12h ahead from the current date (next shift - we want this)
    if($results == $resultsDiff) {
    $resultsFinal = $resultsDiffWeekend;
    }
    //if the results for the current date are not equal with the results for the date with the time 8h ahead 
    //from now (next shift - we want this) that means that the final results should be with the names for 
    //shift 8h ahead from the current date
    if($results != $resultsDiff) {
    $resultsFinal = $resultsDiff;
    }
}
//we print the results line by line, but only when there is some data (to avoid creating empty ones as there is 
//not always six people during the shift)
if(!empty($resultsFinal[4]))
    print_r($resultsFinal[4] . "<BR>");
if(!empty($resultsFinal[5]))
        print_r($resultsFinal[5] . "<BR>");
if(!empty($resultsFinal[6]))
        print_r($resultsFinal[6] . "<BR>");
if(!empty($resultsFinal[7]))
        print_r($resultsFinal[7] . "<BR>");
if(!empty($resultsFinal[8]))
    print_r($resultsFinal[8] . "<BR>");
if(!empty($resultsFinal[9]))
        print_r($resultsFinal[9] . "<BR>");
?>

也许这不是最漂亮或最干净的代码,但是嘿,它似乎在任何条件下都能工作。我希望有人也会觉得有用。

我会尝试这样做:

$currentDate = new DateTime(); //we create an object with the current time
$file = fopen("schedule.csv","r");
$results = array();
//we loop through the file, each line will be an array containing each fields
while (($data = fgetcsv($file, 0, ",")) !== FALSE)
{
    //we create an array that has three elements: the start time, the "-" and the endtime of the shifts
    $shiftTime = explode(" ", $data[2]); 
    //We create two datetime objects that mark the beginning of the shift and the end of the shift
    $startShift = dateTime::createFromFormat("d M Y H:i", $data[0] . " " . $shiftTime[0]);
    $endShift = dateTime::createFromFormat("d M Y H:i", $data[0] . " " . $shiftTime[2]);
    //We compare the two previously created objects to the current date and if 
    //the current date is between the start of the shift and the end of the shift, 
    //we know that person is scheduled to work.
    if($currentDate >= $startShift && $currentDate <= $endShift)
        $results[] = $data;
}

我在代码中添加了注释来解释我所做的。

更新:为了回答Totalizator的询问,这里更详细地解释了我最后的"If"语句的实际作用。首先,变量名中有一个错别字,我已经纠正了……应该读成"结果"而不是"结果"。无论如何,最后一个if语句的目的是确定一个人是否应该在我们说话的时候工作。等式的"正如我们所说"部分包含在我们在脚本的第一行创建的$currentDate变量中。接下来,我们创建另外两个名为$startShift和$endShift的时间戳,它们确定一个人的班次何时开始和何时结束。我们现在所要做的就是确定$currentDate是否落在$startShift和$endShift之间,这就是if的条件所做的。

之后,如果$currentDate确实位于$startShift和$endShift之间,我们将当前行存储在我命名为$results的单独数组中,以便在循环结束时,$results将只包含应该正在工作的人的行。

进一步解释,当你执行

$results[] = $data

它实际上将$data的内容附加在$results数组的末尾。最后,你会得到这样的内容:

$results[0] => array(14 oct 2015, 02, 12:00 - 18:00, 6, "", "John Doe" ...) 
$results[1] => array(15 oct 2015, 01, 18:00 - 00:00, 6, "Jenny Roe", ...)
$results[2] => array(16 oct 2015, 02, 00:00 - 06:00, 6, "Jane Doe", ...)

就是这样了。