2011-06-03 62 views
0

我的兩難處境是,如果我從我的webservices(通過JS調用)請求超過6個月左右(我不知道大概的數字),我什麼都得不到。換句話說,我必須限制它到6個月。如何根據月數來劃分日期範圍?

因此,讓我們考慮這樣的場景:

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

我需要6個月,以使2個不同的網絡servicerequests這樣每次調用請求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); 
     } 
    } 

有誰知道這樣做的簡潔方法?任何人都可以發現任何程序上的缺陷?

+1

順便說一下,我正在工作的服務器沒有PHP 5.3,所以我不能使用'DateTime :: diff' – 2011-06-03 20:21:59

回答

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>"; 
} 

...其中$fetchLimitfetchAll()是任何時間通過字符串可解析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.罰款

+0

完美的作品。優秀的職業生涯:) – 2011-06-10 19:29:04

+0

哇!謝謝!很高興它適合你! – 2011-06-20 21:59:08

0

如果一個月意味着X天,準確地完成此操作的唯一方法是擁有可以執行一天計算的方法。

除非6個月你的意思是6月字面....執行此操作在一個循環:

減去從6月份部分,和遞減一年增加12個月,如果你的月數爲負。然後確定哪個更晚,開始日期或您的遞減日期。

如果您的開始日期晚一些,請使用該日期。如果您的遞減日期晚一些,則打包該日期範圍並循環並開始檢查。