Как я могу разделить диапазон дат на количество месяцев? - PullRequest
0 голосов
/ 04 июня 2011

Моя дилемма заключается в том, что если я запрашиваю более 6 месяцев или около того (я не знаю приблизительное число) из моих веб-сервисов (которые вызывают через JS), я ничего не получаю обратно. Другими словами, я должен ограничить его до 6 месяцев.

Итак, давайте рассмотрим этот сценарий:

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

Мне нужно разделить это на 6 месяцев, чтобы сделать 2 разных запроса к веб-сервису, чтобы каждый звонок запрашивал 6 месяцев.

Так что с $a и $b мне нужно разделить их на максимально возможное количество диапазонов дат, если взять общее количество месяцев, деленное на 6.

Первый диапазон дат, который мне нужен, с 1 июня 2011 года по 31 ноября 2011 года. Второй диапазон дат, который мне нужен, с 1 декабря 2011 года по 1 июля 2012 года.

Идея, которую я имел в виду, заключалась в том, чтобы найти количество месяцев, а затем, если оно больше, чем предельная переменная 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 );
        }
    }

Кто-нибудь знает краткий способ сделать это? Кто-нибудь может обнаружить какие-либо программные недостатки в этом?

Ответы [ 2 ]

2 голосов
/ 04 июня 2011

Попробуйте:

$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.

0 голосов
/ 04 июня 2011

Единственный способ сделать это точно, если месяц означает X дней, - это иметь метод, который может вычислять дни.

Если под 6 месяцами вы не имеете в виду 6 буквальных месяцев ... Сделайте это в цикле:

Вычтите 6 из части месяца и уменьшите год и добавьте 12 к месяцу, если номер вашего месяца отрицательный. Затем определите, что будет позже, дату начала или вашу уменьшенную дату.

Если ваша дата начала позже, используйте эту дату. Если ваша уменьшенная дата более поздняя, ​​упакуйте этот диапазон дат и выполните цикл и начните проверку заново.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...