Сколько дней произошло за определенный промежуток времени

Если у нас есть диапазон дат, такой как:

1 октября 2009 г. - 20 октября 2009 г.

Можем ли мы рассчитать, сколько понедельников произошло за

Ответ на это будет (3)

  M   T   W   T   F   S   S
             *1   2   3   4
  5   6   7   8   9  10  11
 12  13  14  15  16  17  18
 19 *20  21  22  23  24  25
 26  27  28  29  30  31

Можем ли мы сделать это в MySQL, если нет, это можно сделать в PHP или мне нужно создать функцию

6 ответов

Решение

sdt = начальная дата интервала, edt = конечная дата интервала. Измените "2", чтобы отразить день недели, который вы хотите считать.

CREATE FUNCTION NMONDAYS( sdt DATETIME,  edt DATETIME ) 
RETURNS INT DETERMINISTIC RETURN TIMESTAMPDIFF( WEEK, sdt, edt ) 
+ IF( DAYOFWEEK( edt ) >= 2 AND DAYOFWEEK( edt ) < DAYOFWEEK( sdt ),1,0)

Не уверен, если это возможно с MySQL . PHP - ваш друг... есть несколько способов сделать это.. получить начальную и конечную временную метку, используя, вероятно, strtotime... затем запустить цикл for или что-то от начальной временной метки до конечной временной метки, добавив 86400, и на каждом приращении проверять дату ("D", $mkt) == 'Пн' и посмотрите, не увеличился ли ваш понедельник, а затем увеличьте счетчик ур. дал вам грубую идею.. вы можете выяснить код оттуда.

Вы можете начать с чего-то вроде:

select datecol1, TIMESTAMPDIFF(DAY,datecol1,datecol2) as numDays from table;

Затем в PHP вы можете довольно точно определить, сколько понедельников следует за d1, в зависимости от того, какой день недели d1 (вы можете использовать date() и strtotime(), чтобы выяснить это), а также значение numDays в результате. задавать.

РЕДАКТИРОВАТЬ: непроверенный код, но общая идея должна работать:

function daysUntilMonday($date){
    $dayOfWeek = date('w',strtotime($date));  //a number from 0-6, sunday is 0
    $daysTillMonday = (8 - $dayOfWeek) % 7; //modulus is your friend.
    return $daysTillMonday;    
}

function countMondays($start,$numDays){
    $numDays = $numDays - daysUntilMonday($start);
    return floor($numDays/7)+1;
}

Может быть выключен одним, но в целом должен быть правильный подход.

НТН

Или это:

// Pass $date_1, $date_2 as timestamps, $dow as 3-letter abbrev. (e.g. 'Mon').
// Dates can be low to high or high to low.

function dow_between($date_1, $date_2, $dow)
{
    if ($date_2 < $date_1) {
        list($date_2, $date_1) = array($date_1, $date_2);
    }
    for ($num_dow = -1; $date_1 <= $date_2; $num_dow++) {
        $date_1 = strtotime('next ' . $dow, $date_1);
    }
    return $num_dow;
}

Отредактировано для обработки дат в любом порядке.

function daysBetween($from, $to, $round = true) {
    // assume from and two can be valid date() values or strings
    $from = strtotime($from);
    $to = strtotime($to);
    $diff = $to - $from;
    $days = $diff / 86400;
    return ($round) ? floor($days) : round($days, 2);
}

В sql:

SELECT DATEDIFF(
        ADDDATE('20091001', 9 - CASE WHEN DAYOFWEEK('20091001') = 1 THEN 8
                                     WHEN DAYOFWEEK('20091001') = 2 THEN 9
                                     ELSE DAYOFWEEK('20091001') 
                                END), -- first monday after date1
        ADDDATE('20091020', 2 - CASE WHEN DAYOFWEEK('20091020') = 1 THEN 8
                                     ELSE DAYOFWEEK('20091020') 
                                END)  -- first monday before date2
               )/7 + 1 -- divide the difference by 7 gives number of weeks
                       -- add 1 (nb points = nb intervals + 1)
              ) NbMonday
Другие вопросы по тегам