[英]PHP | Get total Months of two Overlapping Date Ranges
i am trying to figure out how to get total Months in between two overlapping date Ranges.我想弄清楚如何在两个重叠的日期范围之间获得总月份数。
eg Date Range from Date-A to Date-B overlapping the Date range of Date-X and Date-Y.例如,从日期-A 到日期-B 的日期范围与日期-X 和日期-Y 的日期范围重叠。
_ Start|Jan - Feb - March - April ------ Nov - Dec|End (DateRange A) Start|Jan - Feb ---- Dec - Jan - Feb|End _
In two date ranges the Jan and Feb Months are colliding.在两个日期范围内,一月和二月发生冲突。 Means Total of 2 Months are there.
意味着总共有 2 个月。 So i want these two months in my array so i can apply different functions on it.
所以我希望这两个月在我的数组中,这样我就可以在它上面应用不同的功能。
eg i have these two dates例如我有这两个日期
$dateRange1Start = "2015-07-01";
$dateRange1End = "2014-06-30";
=-=-=-=====-=-==
$dateRange2Start = "2012-02-01";
$dateRange2End = "2014-12-31";
There are total 6 Months in colliding between these two date ranges.这两个日期范围之间总共有 6 个月的时间冲突。 i want to get these 6 Months.
我想要这 6 个月。
I tried to search for help in google, but mostly i get less than or greater than signs.我试图在谷歌搜索帮助,但大多数情况下我得到的结果小于或大于符号。 but specifically like this.
但特别喜欢这个。 I tried to implement my own logic but its not getting me anywhere, sadly to only more problems :(
我试图实现我自己的逻辑,但它没有让我在任何地方,可悲的是只有更多的问题:(
i am trying to get results like this我试图得到这样的结果
$collidingDates = array("2014-07","2014-08","2014-09","2014-10","2014-11","2014-12");
Any help would be appreciated.任何帮助,将不胜感激。 :)
:)
=-=-=-=-=-=-=-==-=-=-=-=-=-=-=-=--=-= ==-=-=-=-=-=-=-==-=-=-=-=-=-=-=-=--=-=
UPDATE:更新:
Here is what i have done so far, yes getting some code from here and there.这是我到目前为止所做的,是的,从这里和那里获取一些代码。 and tweaking it a bit up to fulfill my requirements.
并稍微调整一下以满足我的要求。
//Getting all Months from First Date Range
$start = (new DateTime('2014-06-01'))->modify('first day of this month');
$end = (new DateTime('2015-05-06'))->modify('first day of next month');
$interval = DateInterval::createFromDateString('1 month');
$firstPeriod = new DatePeriod($start, $interval, $end);
//Getting all Months from Second Date Range.
$start = (new DateTime('2012-02-01'))->modify('first day of this month');
$end = (new DateTime('2014-12-31'))->modify('first day of next month');
$interval = DateInterval::createFromDateString('1 month');
$secondPeriod = new DatePeriod($start, $interval, $end);
$collidingDates = array();
foreach ($firstPeriod as $f_dt) {
foreach($secondPeriod as $s_dt){
if($f_dt->format("Y-m") === $s_dt->format("Y-m")){
array_push($collidingDates,$f_dt->format("Y-m"));
}
}
}
echo "<pre>";
print_r($collidingDates);
i got this output.我得到了这个输出。
Array
(
[0] => 2014-06
[1] => 2014-07
[2] => 2014-08
[3] => 2014-09
[4] => 2014-10
[5] => 2014-11
[6] => 2014-12
)
But i think i am getting 1 extra month 2014-06, not sure how O_o??但我想我会在 2014-06 年多 1 个月,不知道 O_o 怎么样??
This is a two step process.这是一个两步过程。 First you need to establish the narrowest date range from the start and end dates.
首先,您需要从开始日期和结束日期确定最窄的日期范围。 Then list the months between those dates.
然后列出这些日期之间的月份。
// An array of start and end dates. There are just 2 in this example but you
// could have as many as you like in the same "start, then end" format.
$ranges = [
[new DateTime('2014-07-01'), new DateTime('2015-06-30')],
[new DateTime('2012-02-01'), new DateTime('2014-12-31')]
];
// Reduce the ranges to one set of two dates, the latest of the start dates
// and the earliest of the end dates.
$range = array_reduce($ranges, function($carry, $item){
return $carry
? [max($carry[0], $item[0]), min($carry[1], $item[1])]
: $item;
});
var_dump($range);
/*
array (size=2)
0 =>
object(DateTime)[1]
public 'date' => string '2014-07-01 00:00:00.000000' (length=26)
public 'timezone_type' => int 3
public 'timezone' => string 'Europe/London' (length=13)
1 =>
object(DateTime)[4]
public 'date' => string '2014-12-31 00:00:00.000000' (length=26)
public 'timezone_type' => int 3
public 'timezone' => string 'Europe/London' (length=13)
*/
// Shift both dates to the first of the month. Strictly speaking, we only
// need to do this with the start date.
$range = array_map(function($date){
return $date->modify("first day of this month");
}, $range);
var_dump($range);
/*
array (size=2)
0 =>
object(DateTime)[1]
public 'date' => string '2014-07-01 00:00:00.000000' (length=26)
public 'timezone_type' => int 3
public 'timezone' => string 'Europe/London' (length=13)
1 =>
object(DateTime)[4]
public 'date' => string '2014-12-01 00:00:00.000000' (length=26)
public 'timezone_type' => int 3
public 'timezone' => string 'Europe/London' (length=13)
*/
$months = [];
$interval = new DateInterval("P1M");
for ($month = $range[0]; $month <= $range[1]; $month->add($interval)) {
$months[] = $month->format("Y-m");
}
var_dump($months);
/*
array (size=6)
0 => string '2014-07' (length=7)
1 => string '2014-08' (length=7)
2 => string '2014-09' (length=7)
3 => string '2014-10' (length=7)
4 => string '2014-11' (length=7)
5 => string '2014-12' (length=7)
*/
I think you are looking for this:我想你正在寻找这个:
$start = (
new DateTime('2015-12-02'))
->modify('first day of this month');
$end = (new DateTime('2016-05-06'))->modify('first day of next month');
$interval = DateInterval::createFromDateString('1 month');
$period = new DatePeriod($start, $interval, $end);
foreach ($period as $dt) {
echo $dt->format("Y-m") . "<br>\n";
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.