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.