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

时间:2015-10-14 19:57:45

标签: php csv

我有一个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!)并在某天发布回复作为证据。

2 个答案:

答案 0 :(得分:0)

我尝试做这样的事情:

$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的询问时,这里有一个更详细的解释,说明我的最终&#34; If&#34;声明确实如此。首先,我修正的变量名称中有一个拼写错误...应该阅读&#34;结果&#34;而不是&#34;结果&#34;。无论如何,最终的目标是&#34;如果&#34;声明是确定一个人是否应该在我们发言时工作。 &#34;正如我们所说&#34;等式的一部分包含在我们在脚本第一行创建的$ currentDate变量中。接下来,我们再创建两个名为$ startShift和$ endShift的时间戳,它们确定一个人的班次何时开始以及何时结束。我们现在要做的就是确定$ currentDate是否介于$ startShift和$ endShift之间,这就是if的条件。

之后,如果$ currentDate实际上落在$ startShift和$ endShift之间,我们将当前行存储在一个单独的数组中,我将其命名为$ results,这样在循环结束时,$ results将只包含那些应该现在正在工作的人。

进一步解释,当你做

$results[] = $data

它实际上在$ results数组的末尾追加$ data的内容。所以最后,你会有这样的事情:

$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", ...)

所以你有它。我希望这能解决问题。

答案 1 :(得分:0)

感谢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小时(周末 AND 某些随机天数)。基于此,我不能简单地看8或12小时,因为这会产生各种问题,如:

  • 在12h班次开始时向前看8h(显示同一班次)

  • 在8h班次结束前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>");
?>

也许这不是最美丽或最干净的代码,但嘿,它似乎在各种条件下都能正常工作。我希望有人会发现它也很有用。