MySQL: рассчитать разницу между датой и временем - только во время M-F «Рабочая неделя» - PullRequest
2 голосов
/ 08 февраля 2010

Мне нужно рассчитать разницу между начальной датой / временем и конечной датой / временем. Но я хочу сделать это только для 5-дневной рабочей недели (исключая субботу / воскресенье в качестве дней). Каков наилучший способ сделать это? Я думаю, что с даты, я должен получить день недели, и если это будний день, то я добавлю в аккумулятор. Если нет, то я ничего не добавляю.

Я уверен, что кто-то делал это раньше, но я не мог найти что-то в поисках. Любые ссылки или другая помощь будут очень полезны.

Большое спасибо,

Bruce

Ответы [ 2 ]

4 голосов
/ 08 февраля 2010

DAYOFWEEK возвращает 1 для воскресенья и 7 для субботы. Я не уверен, как настроена ваша схема, но при этом будет выполняться TIMEDIFF из двух дат, которые относятся к рабочей неделе с понедельника по пятницу.

select TIMEDIFF(date1,date2) from table 
where DAYOFWEEK(date1) not in (1,7) and DAYOFWEEK(date2) not in (1,7)

Функции MySQL DATE / TIME

РЕДАКТИРОВАТЬ : Из комментария Брюса о праздниках. Если у вас есть таблица, полная праздничных дат, что-то вроде этого будет работать, чтобы исключить обработку в эти дни:

select TIMEDIFF(date1,date2) from table 
where date1 not in (select holiday from holiday_table) and
date2 not in (select holiday from holiday_table) and
DAYOFWEEK(date1) not in (1,7) and DAYOFWEEK(date2) not in (1,7)
2 голосов
/ 08 февраля 2010

NETWORKDAYS () "Возвращает количество полных рабочих дней между start_date и end_date. Рабочие дни исключают выходные и любые даты, указанные в праздничные дни. Используйте NETWORKDAYS для расчета вознаграждений работникам, которые начисляются на основе количества дней, отработанных в течение определенного срока. " в соответствии с файлом справки Excel 2007

Описание «между» немного неточно, поскольку оно включает даты начала и окончания, то есть networkdays (21-01-2010. 22-01-2010) = 2. Также не учитывается время.

Вот функция в PHP, которая даст те же результаты. Он не работает должным образом, если дата окончания меньше даты начала, и ничего не делает для праздников (см. Ниже функцию).

function networkdays($startdate, $enddate)
  {
     $start_array = getdate(strtotime($startdate));
     $end_array = getdate(strtotime($enddate));

     // Make appropriate Sundays
     $start_sunday = mktime(0, 0, 0, $start_array[mon], $start_array[mday]+(7-$start_array[wday]),$start_array[year]);
     $end_sunday = mktime(0, 0, 0, $end_array[mon], $end_array[mday]- $end_array[wday],$end_array[year]);

     // Calculate days in the whole weeks
     $week_diff = $end_sunday - $start_sunday;
     $number_of_weeks = round($week_diff /604800); // 60 seconds * 60 minutes * 24 hours * 7 days = 1 week in seconds
     $days_in_whole_weeks = $number_of_weeks * 5;

     //Calculate extra days at start and end
     //[wday] is 0 (Sunday) to 7 (Saturday)
     $days_at_start = 6 - $start_array[wday];
     $days_at_end = $end_array[wday];

     $total_days = $days_in_whole_weeks + $days_at_start + $days_at_end;

     return $total_days;
}

Чтобы учесть праздники, вам нужно определить количество дней, используя эту функцию, а затем использовать запрос типа

Select count (holiday_date) from holidays
where holiday_date between start_date and end_date
and DAYOFWEEK(holiday_date) not in (1,7)

Будьте осторожны, чтобы не было проблем с обработкой end_date как 00:00 (т. Е. Первым делом утром) - вам, возможно, придется установить его на 23:59:59, чтобы он работал правильно. Все зависит от того, как хранятся ваши праздники.

Чтобы вернуть выходные в тот же период времени и вычесть их из числа, о котором вы впервые подумали.

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