如何按日期划分日期范围?

时间:2011-06-03 20:14:53

标签: php date

我的困境是,如果我从我的网络服务(通过JS调用)请求超过6个月左右(我不知道大概的数字),我什么也得不回来。换句话说,我必须将它限制在6个月。

让我们考虑一下这个场景:

$a = strtotime('June 3, 2011'); 
$b = strtotime('June 3, 2012');

我需要将其拆分6个月,以便制作2个不同的网络服务请求,以便每个呼叫请求6个月。

因此,对于$a$b,我需要在将总月数除以6时将这些日期范围拆分为尽可能多的日期范围。

我需要的第一个日期范围是2011年6月1日到2011年11月31日。我需要的第二个日期范围是2011年12月1日到2012年7月1日。

我想到的想法是查找月数,然后如果它大于限制变量6,则执行循环并将每个循环的初始日期增加6个月。

伪代码(我实际上最初在JS中编写它,但认为在PHP中更容易,因为我不必处理多个异步请求行为):

   var numMonths = monthDiff ( a, b ), ret = [], limit = 6, loopLimit = Math.ceil( numMonths / limit ), ranges = [];

    if ( numMonths > limit ) {

        for ( var i = 0; i<loopLimit; i++ ) {
            var start = new Date(b);
            var end = new Date ( b.setMonth( b.getMonth() + limit ) );
            ranges.push( start, end );
        }
    }

有没有人知道这样做的简洁方法?有人能发现这方面的任何程序性缺陷吗?

3 个答案:

答案 0 :(得分:2)

尝试:

$a = strtotime("June 3, 2011 00:00:00Z"); 
$b = strtotime("June 3, 2012 00:00:00Z");
fetchAll($a,$b);

function fetchAll($a,$b) {
  $fetchLimit = "6 months";  // or, say, "180 days"; a string

  if ($b <= strtotime(gmdate("Y-m-d H:i:s\Z",$a)." +".$fetchLimit)) {
    // it fits in one chunk
    fetchChunk($a,$b);
  }
  else {  // chunkify it!
    $lowerBound = $a;
    $upperBound = strtotime(gmdate("Y-m-d H:i:s\Z",$a)." +".$fetchLimit);
    while ($upperBound < $b) { // fetch full chunks while there're some left
      fetchChunk($lowerBound,$upperBound);
      $lowerBound = $upperBound;
      $upperBound = strtotime(gmdate("Y-m-d H:i:s\Z",$lowerBound)." +".$fetchLimit);
    }
    fetchChunk($lowerBound,$b); // get last (likely) partial chunk
  }

}

function fetchChunk($a,$b) {
  /* insert your function that actually grabs the partial data */
  //
  // for test, just display the chunk range:
  echo gmdate("Y-m-d H:i:s\Z",$a)." to ".gmdate("Y-m-d H:i:s\Z",$b)."<br>";
}

... $fetchLimit中的fetchAll()strtotime()可解析的任何持续时间字符串。然后,您可以继续将每个fetchChunk()的输出附加到最初为空的变量,该变量稍后由fetchAll()返回。

此示例按预期获取两个六个月的“块”。将$b更改为一天后,会添加仅包含额外一天的第三个块:

2011-06-03 00:00:00Z to 2011-12-03 00:00:00Z
2011-12-03 00:00:00Z to 2012-06-03 00:00:00Z
2012-06-03 00:00:00Z to 2012-06-04 00:00:00Z

当然,PHP 5.3有一些更优雅的时间函数,如DateTime::diff,但上面的代码在PHP 5.2.x中应该可以正常工作。

答案 1 :(得分:0)

如果一个月意味着X天,那么准确执行此操作的唯一方法是使用可以执行日计算的方法。

除非6个月你的意思是6个月的数字....这样做是循环的:

从月份部分减去6,并减少年份,如果您的月份数为负,则将12添加到月份。然后确定哪个是后期,开始日期或递减日期。

如果您的开始日期晚些时候,请使用该日期。如果您的递减日期稍晚,则打包该日期范围并循环并开始检查。

答案 2 :(得分:0)

另一种方法是:

$a = strtotime("2018-12-01");
$b = strtotime("2020-12-01");
$makeArray = array();
function addDate($date){
    return strtotime(gmdate("Y-m-d", $date)." +4 months");
}
array_push($makeArray, array("start" => date("Y-m-d", $a), "end" => date("Y-m-d", addDate($a))));

while ($c < $b) {
    $a = addDate($a);
    $c = addDate($a);
    if ($c >= $b) {
        $c = $b;
    }
    array_push($makeArray, array("start" => date("Y-m-d", $a), "end" => date("Y-m-d", $c)));
}
print_r($makeArray);