【问题标题】:PHP | Get total Months of two Overlapping Date RangesPHP |获取两个重叠日期范围的总月数
【发布时间】:2016-04-23 09:24:19
【问题描述】:

我想弄清楚如何在两个重叠的日期范围之间获取总月数。

例如 从 Date-A 到 Date-B 的日期范围与 Date-X 和 Date-Y 的日期范围重叠。

_ Start|Jan - Feb - March - April ------ Nov - Dec|End (DateRange A) Start|Jan - Feb ---- Dec - Jan - Feb|End _

在两个日期范围内,一月和二月发生冲突。意味着总共有 2 个月。 所以我希望这两个月在我的数组中,这样我就可以在上面应用不同的函数。

例如我有这两个日期

$dateRange1Start = "2015-07-01";
$dateRange1End = "2014-06-30"; 
=-=-=-=====-=-==
$dateRange2Start = "2012-02-01";
$dateRange2End = "2014-12-31";

这两个日期范围之间总共有 6 个月的冲突。我想要这 6 个月。

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

我正在尝试得到这样的结果

$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);

我得到了这个输出。

Array
    (
        [0] => 2014-06
        [1] => 2014-07
        [2] => 2014-08
        [3] => 2014-09
        [4] => 2014-10
        [5] => 2014-11
        [6] => 2014-12
    )

但我想我会多得到 1 个月 2014-06,不知道怎么O_o??

【问题讨论】:

  • 您是否尝试过将时间转换为 DateTime 对象并使用 ->diff() ,?
  • 不,因为我不确定如何在两个日期范围之间获取月份。我有两个日期的差异,但不是两个日期范围。

标签: php date


【解决方案1】:

这是一个两步过程。首先,您需要从开始日期和结束日期确定最窄的日期范围。然后列出这些日期之间的月份。

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

【讨论】:

    【解决方案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";
    
     }
    

    【讨论】:

    • 先生,您所做的只有一个日期范围,我正在寻找两个日期范围的比较。
    • 如果您看到问题,它有两个日期范围,日期范围 1 和日期范围 2。表示总共 4 个日期。 2 个开始日期和 2 个结束日期。
    猜你喜欢
    • 2017-06-08
    • 1970-01-01
    • 2019-07-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-03
    相关资源
    最近更新 更多