My dilemma is that if I request more than 6 months or so ( I do not know the approximate number ) from my webservices ( which gets called via JS ), I get nothing back. In other words, I have to limit it to 6 months.
So let’s consider this scenario:
$a = strtotime('June 3, 2011');
$b = strtotime('June 3, 2012');
I need to split this up by 6 months in order to make 2 distinct web servicerequests so that each call requests 6 months.
So with $a
and $b
, I need to split these up into as many date ranges as possible when taking the amount of months total divided by 6.
The first date range I need is from June 1, 2011 to November 31, 2011. The second date range I need is from December 1, 2011 to July 1, 2012.
The idea I had in mind was finding the number of months, then if it was greater than the limit variable 6
, do a loop and increment the initial date by 6 months per loop.
Pseudo-code ( I actually initially wrote it in JS but figured it’d be easier to do in PHP because I wouldn’t have to deal with multiple asynchronous request behaviour ):
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 );
}
}
Does anyone know of a succinct way of doing this? Can anyone spot any programmatic flaws in this?
Advertisement
Answer
Try:
$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:sZ",$a)." +".$fetchLimit)) {
// it fits in one chunk
fetchChunk($a,$b);
}
else { // chunkify it!
$lowerBound = $a;
$upperBound = strtotime(gmdate("Y-m-d H:i:sZ",$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:sZ",$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:sZ",$a)." to ".gmdate("Y-m-d H:i:sZ",$b)."<br>";
}
…where $fetchLimit
in fetchAll()
is any duration string parseable by strtotime()
. You could then keep appending the output of each fetchChunk()
to an initially blank variable which is later returned by fetchAll()
.
This example fetches two six-month “chunks”, as expected. Changing $b
to one day later adds a third chunk containing only that extra day:
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
Of course, PHP 5.3 has somewhat more elegant time functions like DateTime::diff
, but the code above should work fine in PHP 5.2.x.