我有一个每小时的项目列表,但它们不是每小时都发生,所以我的列表中有漏洞。我也有一个空白的模板,每小时,但任何类型的diff工具不会匹配相同的时间和日期的行。我怎样才能填满我的清单来打发空闲时间呢?我正在考虑沿着regex匹配到计数的行,并将模板中的0替换为计数。
Counted List
4/1/2014,4:00 PM,5
4/1/2014,6:00 PM,3
4/1/2014,7:00 PM,4
4/1/2014,9:00 PM,5
4/1/2014,10:00 PM,4
4/2/2014,7:00 AM,3
4/2/2014,8:00 AM,3
Template
4/1/2014,12:00 AM,0
4/1/2014,1:00 AM,0
4/1/2014,2:00 AM,0
4/1/2014,3:00 AM,0
4/1/2014,4:00 AM,0
PHP:
$regex = '~(d{1,2}/d{1,2}/d{4}),(d{1,2}:00 [AP]M),(d+)~';
$oneHour = new DateInterval('PT1H');
$lines = explode("n", $data);
$count = count($lines);
$final = array();
foreach($lines as $key => $line) {
preg_match($regex, $line, $currentMatches);
$final[] = $currentMatches[0];
if($key < $count - 1) {
preg_match($regex, $lines[$key + 1], $nextMatches);
$currentDate = new DateTime($currentMatches[1] . ' ' . $currentMatches[2]);
$nextDate = new DateTime($nextMatches[1] . ' ' . $nextMatches[2]);
while($nextDate->getTimestamp() - $currentDate->getTimestamp() != 60 * 60) {
$currentDate = $currentDate->add($oneHour);
$final[] = $currentDate->format('n/j/Y,g:i A,0');
}
}
}
$data = implode("n", $final);
输出(使用你的输入作为$data):
4/1/2014,4:00 PM,5
4/1/2014,5:00 PM,0
4/1/2014,6:00 PM,3
4/1/2014,7:00 PM,4
4/1/2014,8:00 PM,0
4/1/2014,9:00 PM,5
4/1/2014,10:00 PM,4
4/1/2014,11:00 PM,0
4/2/2014,12:00 AM,0
4/2/2014,1:00 AM,0
4/2/2014,2:00 AM,0
4/2/2014,3:00 AM,0
4/2/2014,4:00 AM,0
4/2/2014,5:00 AM,0
4/2/2014,6:00 AM,0
4/2/2014,7:00 AM,3
4/2/2014,8:00 AM,3
解释:
首先,$data
是您的输入数据(来自文件?),它包含由新行分隔的日期/时间/计数字符串。然后我们使用表达式$regex = '~(d{1,2}/d{1,2}/d{4}),(d{1,2}:00 [AP]M),(d+)
,它假设您的数据总是以格式mm/dd/YYYY,hh:00 XM,#
。这里需要注意的是,根据您的示例,我们根本不关心分钟,并且对格式非常严格。
同样,假设每一行都匹配正则表达式。如果没有,则需要在这里添加一些条件。首先匹配当前行并将其添加到一个新数组中。然后,如果不在数组的末尾,就匹配下一行。现在我们比较这些日期,并通过while
循环下一个日期不是当前日期的未来1小时。我们更新当前日期,向新数组添加一个计数为0的占位符,然后在一个小时后的下一个日期时停止。我们将在foreach
的下一次迭代中继续这一行。
链接:
-
preg_match
-
DateInterval
-
DateTime
-
DateTime::diff()
-
DateTime::getTimestamp()
-
DateTime::add()
-
DateTime::format()