我有一个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!)并在某天发布回复作为证据。
答案 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>");
?>
也许这不是最美丽或最干净的代码,但嘿,它似乎在各种条件下都能正常工作。我希望有人会发现它也很有用。