PHP |获取两个重叠日期范围的总月份数

PHP |获取两个重叠日期范围的总月份数,php,date,Php,Date,我试图找出如何在两个重叠的日期范围之间获得总月数 e-g 日期范围从日期-A到日期-B,与日期-X和日期-Y的日期范围重叠 |开始|一月-二月-三月-四月------十一月-十二月|结束(日期范围A) 开始|一月-二月----十二月-一月-二月|结束 在两个日期范围内,1月和2月是相互冲突的。表示总共有2个月。 所以我希望这两个月在我的数组中,这样我就可以对它应用不同的函数 我有这两个约会 $dateRange1Start = "2015-07-01"; $dateRange1End = "20

我试图找出如何在两个重叠的日期范围之间获得总月数

e-g 日期范围从日期-A到日期-B,与日期-X和日期-Y的日期范围重叠

|开始|一月-二月-三月-四月------十一月-十二月|结束(日期范围A)
开始|一月-二月----十二月-一月-二月|结束

在两个日期范围内,1月和2月是相互冲突的。表示总共有2个月。 所以我希望这两个月在我的数组中,这样我就可以对它应用不同的函数

我有这两个约会

$dateRange1Start = "2015-07-01";
$dateRange1End = "2014-06-30"; 
=-=-=-=====-=-==
$dateRange2Start = "2012-02-01";
$dateRange2End = "2014-12-31";
这两个日期范围总共相撞6个月。我想要这6个月

我试着在谷歌上搜索帮助,但大多数情况下我得到的都是小于或大于符号。但特别是像这样。我试图实现我自己的逻辑,但它没有让我走到任何地方,可悲的是,只有更多的问题:(

我正试图得到这样的结果

$collidingDates = array("2014-07","2014-08","2014-09","2014-10","2014-11","2014-12");
任何帮助都将不胜感激。:)

=-=-=-=-=-=-=-==-=-=-=-=-=-=-=-=--=-=

更新:

这里是我到目前为止所做的,是的,从这里和那里获得一些代码。并对其进行调整以满足我的要求

//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);
但我想我会多得到一个月
2014-06年,不知道怎么办?

我想你在找这个:

// 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)
 */
$start=(
新日期时间('2015-12-02'))
->修改(“本月第一天”);
$end=(新日期时间('2016-05-06'))->modify('下个月的第一天');
$interval=DateInterval::createFromDateString('1个月');
$period=newdateperiod($start、$interval、$end);
foreach(期间为$dt){
echo$dt->格式(“Y-m”)。“
\n”; }
这是一个两步流程。首先,您需要确定从开始日期到结束日期的最窄日期范围。然后列出这些日期之间的月份

//开始日期和结束日期的数组。本例中只有2个,但您
//可以有相同的“开始,然后结束”格式的任意数量。
$ranges=[
[新日期时间('2014-07-01'),新日期时间('2015-06-30'),
[新日期时间('2012-02-01'),新日期时间('2014-12-31')]
];
//将范围减少为一组两个日期,即最晚的开始日期
//以及最早的结束日期。
$range=array\u reduce($ranges,function($carry,$item){
返回$carry
?[最大($carry[0],$item[0]),最小($carry[1],$item[1])]
:$项目;
});
var_dump($范围);
/*
数组(大小=2)
0 => 
对象(日期时间)[1]
公共“日期”=>string“2014-07-01 00:00:00.000000”(长度=26)
公共“时区类型”=>int 3
公共“时区”=>字符串“欧洲/伦敦”(长度=13)
1 => 
对象(日期时间)[4]
公共“日期”=>string“2014-12-31 00:00:00.000000”(长度=26)
公共“时区类型”=>int 3
公共“时区”=>字符串“欧洲/伦敦”(长度=13)
*/
//将两个日期都移到月的第一天。严格地说,我们只是
//需要在开始日期之前完成此操作。
$range=数组\映射(函数($date){
返回$date->modify(“本月第一天”);
}美元范围);
var_dump($范围);
/*
数组(大小=2)
0 => 
对象(日期时间)[1]
公共“日期”=>string“2014-07-01 00:00:00.000000”(长度=26)
公共“时区类型”=>int 3
公共“时区”=>字符串“欧洲/伦敦”(长度=13)
1 => 
对象(日期时间)[4]
公共“日期”=>string“2014-12-01 00:00:00.000000”(长度=26)
公共“时区类型”=>int 3
公共“时区”=>字符串“欧洲/伦敦”(长度=13)
*/
$months=[];
$interval=新日期间隔(“P1M”);
对于($month=$range[0];$month add($interval)){
$months[]=$month->格式(“Y-m”);
}
var_dump(月);
/*
数组(大小=6)
0=>字符串“2014-07”(长度=7)
1=>字符串“2014-08”(长度=7)
2=>字符串“2014-09”(长度=7)
3=>字符串“2014-10”(长度=7)
4=>字符串“2014-11”(长度=7)
5=>字符串“2014-12”(长度=7)
*/

您是否尝试过将时间转换为DateTime对象并使用->diff(),?没有,因为我不知道如何在两个日期范围之间获得月数。主席先生,你所做的只是一个日期范围,我想比较两个日期范围。如果你看到问题,它有两个日期范围,日期范围1和日期范围2。指总共4个日期。2个开始日期和2个结束日期。
 $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";

 }
// 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)
 */