我的困境是,如果我从我的网络服务(通过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 );
}
}
有没有人知道这样做的简洁方法?有人能发现这方面的任何程序性缺陷吗?
答案 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);