2015-10-14 171 views
0

我有一個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!),並且有一天會在這裏發表一個答覆作爲證明。

回答

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的詢問,這裏是我最後的「If」聲明實際上做了什麼更詳細的解釋。首先,在我修正的變量名稱中有一個拼寫錯誤...它應該被讀作「結果」而不是「結果」。無論如何,最後的「如果」聲明的目的是確定一個人是否應該在我們說話時工作。等式中的「我們說話」部分包含在我們在腳本的第一行創建的$ currentDate變量中。接下來,我們創建兩個名爲$ startShift和$ endShift的時間戳,它們確定一個人的輪班何時開始以及何時結束。我們現在要做的就是確定$ currentDate是否落在$ startShift和$ endShift之間,這就是if的條件。然後,如果$ currentDate實際上落在$ startShift和$ endShift之間,我們將當前行存儲在一個單獨的數組中,並將其命名爲$ results,以便在循環結束時,$ results只包含行那些現在應該工作的人。

爲了進一步解釋,當你做

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

所以你有它。我希望這可以清除事情。

+0

謝謝!這看起來很整齊。我可以理解你做到這一點的方式,但是對於我來說不太清楚的是''results = array();'在開頭(它代表什麼?)和最後的'if' - ('$ result [ ] = $ data;')如何在本例中打印輸出? – totalizator

+0

我在帖子中添加了一些解釋。如果事情還不清楚,不要猶豫再問一次。 – Osuwariboy

+0

就像我期望的一樣,但仍然讓我感到困惑。謝謝!問題是我無法填充'$ results'。 'schedule.csv'包含有效的條目,'$ startShift'和'$ endShift'被填充,但是當涉及到'if'語句時,沒有什麼可以讀取'$ results' - 只是一個空的'Array()' 。你確定我可以比較'$ currentData'是一個Unix時間戳,其他值是否像DateTime對象?我添加了'date_default_timezone_set('Europe/London');'以確保生成的時間是正確的,並且我已經嘗試了'$ currentDate = date('Y-m-d H:i:s:u');'''''''''' – totalizator

0

謝謝你的幫助Osuwariboy!這感覺像是一場艱苦的鬥爭,但它終於奏效了。謝謝你。

我會盡力與解決方案完全描述的情況:

我有時間表。CSV文件格式像這樣(日期,未使用的編號,換擋時間,輪班lenght,姓名(最多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小時提前因爲這會產生類似的各種問題。

  • 在12小時的班次開始前看8小時(顯示相同的班次)

  • 提前近8小時輪班結束尋找12H(跳過下一個)

已經有一個問題也與移位日期,如在哪裏。 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>"); 
?> 

也許這不是最漂亮的還是乾淨的代碼,但嘿,似乎每個條件下進行工作。我希望有人會發現它也很有用。