有两个日期数组(mm / dd / yyyy)
array(2) {
["useless_range"]=>
array(4) {
[0]=>
string(10) "08/15/2014"
[1]=>
string(10) "08/30/2014"
[2]=>
string(10) "09/10/2014"
[3]=>
string(10) "09/20/2014"
}
["range"]=>
array(2) {
[0]=>
string(10) "08/01/2014"
[1]=>
string(10) "10/31/2014"
}
}
考虑数组range_useless是假日,罢工或类似的东西。它已经排序了。 如何从给定的数组范围中获得有用的范围?
对于那个例子,我希望范围是
'08/01/2014 to 08/14/2014 **and** 08/31/2014 to 09/09/2014 **and** 09/21/2014 to 10/31/2014'
我的第一个解决方案是创建一个包含范围之间所有日期的数组,然后使用in_array创建完整的字符串循环,但我认为可能存在更好的解决方案
在所有范围之间创建所有日期的代码
$strDateFrom = '2014/08/15';
$strDateTo = '2014/08/30';
// takes two dates formatted as YYYY-MM-DD and creates an
// inclusive array of the dates between the from and to dates.
$aryRange=array();
$iDateFrom=mktime(1,0,0,substr($strDateFrom,5,2), substr($strDateFrom,8,2),substr($strDateFrom,0,4));
$iDateTo=mktime(1,0,0,substr($strDateTo,5,2), substr($strDateTo,8,2),substr($strDateTo,0,4));
if ($iDateTo>=$iDateFrom) {
array_push($aryRange,date('Y-m-d',$iDateFrom)); // first entry
while ($iDateFrom<$iDateTo) {
$iDateFrom+=86400; // add 24 hours
array_push($aryRange,date('Y-m-d',$iDateFrom));
}
}
print_r($aryRange);
答案 0 :(得分:1)
有趣的挑战:)!所以我试了一下:
$myDates = array(
"useless_range" => array(
"01/08/2015",
"01/15/2015",
"09/10/2015",
"09/20/2015"
),
"range" => array(
"08/01/2015",
"10/31/2015"
)
);
// results of strotime
$dateStart = 1420066800; //01/01/2015
$dateTo = 1422658800; // 31/01/2015
$tab = $myDates['useless_range'];
$len = count($tab);
$result = array();
$previous = $dateStart;
for($i = 0; $i < $len; $i++){
$position = $tab[$i]; // we get the current element
$iPosition = strtotime($position); // strotime it
if($previous < $iPosition && $iPosition < $dateTo){ // if the useless date is in the range
if($i % 2 == 0){ //if start of range
$result[] = array("start" => date("Y-m-d", $previous + 3600*24), "end" => date("Y-m-d", $iPosition));
}
$previous = $iPosition;
}
else { // the date is out of range, we finish the result and leave the loop
$result[] = array("start" => date("Y-m-d", $previous), "end" => date("Y-m-d", $dateTo + 3600*24));
break; //end of search
}
}
print_r($result);
输出结果:
Array
(
[0] => Array
(
[start] => 2015-01-01
[end] => 2015-01-08
)
[1] => Array
(
[start] => 2015-01-15
[end] => 2015-01-31
)
)
现在创建句子:
$sentences = array();
foreach($result as $elem){
$sentences[] = $elem['start']." to ".$elem['end'];
}
echo implode(' **and** ', $sentences);
答案 1 :(得分:1)
好的,这与你所获得的并没有太大的不同,但它是另一种观点,我使用的是strtotime()
函数,而不是mktime()
至少看起来更好。
我假设输入已经过验证,并且我忽略了角落情况,例如当所需范围/周期的开始日期在第一个“无用的”范围内时。范围,或结束日期是无用的&#39;范围,但如果有必要,这可以很容易地验证。
我只是想让你分享我将如何解决这个问题。
这是我的代码:
<?php
$uselessRanges = [ "08/15/2014", "08/30/2014", "09/10/2014", "09/20/2014" ];
$range = [ "08/01/2014", "10/31/2014" ];
// Convert to timestamps for easier manipulation
$rangeTs = array_map( 'strtotime', $range );
$uselessRangesTs = array_map( 'strtotime', $uselessRanges );
// Let the first date be the start of the whole range
$finalResult = [ array_shift( $rangeTs ) ];
/**
* Assuming that the useless ranges array is of the following format:
* $useless = [ 'start_useless_range_1', 'end_useless_range_1', 'start_useless_range_2', 'end_useless_range_2', ... ]
*
* For each of the useless range entries we decide whether to take the previous or the next day based on the parity of the index
*/
for( $i = 0; $i < count( $uselessRangesTs); $i++ ){
// Whether we should take the previous or the next day
$diff = $i % 2 === 0 ? -86400 : 86400;
$finalResult[] = $uselessRangesTs[$i] + $diff;
}
// Finally add the end of the whole range
$finalResult[] = array_shift( $rangeTs );
foreach( $finalResult as $date ){
echo date('m/d/Y', $date) . '<br />';
}
答案 2 :(得分:1)
假设您只需要生成一个字符串,并且日期已经过验证并按顺序排列,我就不会为日期函数烦恼了。以下是我将如何做的一个简单示例:
$dates = array(
"useless_range" => array(
"08/15/2014",
"08/30/2014",
"09/10/2014",
"09/20/2014"
),
"range" => array(
"08/01/2015",
"10/31/2015"
)
);
$str = array();
for ( $i = 0; $i < sizeof($dates['useless_range']); $i += 2 ) {
$str[] = sprintf('%s and %s', $dates['useless_range'][$i], $dates['useless_range'][$i+1]);
}
array_unshift($str, $dates['range'][0]);
$str[] = $dates['range'][1];
$str = implode(' to ',$str);
echo $str;
// 08/01/2015 to 08/15/2014 and 08/30/2014 to 09/10/2014 and 09/20/2014 to 10/31/2015
说明:
一般的想法是建立一个句子,所以我不打扰日期或范围或任何东西。想象一下需要拼凑在一起的单词。最终结果必须是:
&#34; range0 到 useless_range0 和 useless_range1 到 useless_range2 和 useless_range3 到 range1 &#34;
这可以这样分解:
[ range0 ]到[ useless_range0 和 useless_range1 ]到[ useless_range2 和 useless_range3 ]到[ range1 ]
使用&#34;内爆可以很容易地实现这一点。到&#34;作为分隔符。我们只需要生成数组,其中 range0 作为第一个元素, range1 作为最后一个元素,以及每一句话(两个连续日期+&#34;和&#34) ;)之间。这是一个简单的循环+ array_shift / unshift。
注意:如果您的日期未经过验证,或者您需要检查重叠或任何类似的东西,那么您很可能必须像您一样构建一系列日期。