Страница 1 из 1

Как Посчитать кол-во рабочих часов

Добавлено: 07 янв 2007, 12:19
Snickbw
Кто нибудь сталкивался с такой проблемой?

Задан рабочий день: 08:00-17:00 ежедневно
Устройство принято в ремонт : 14:30 date1
Устройство выдано из ремонта : 09:45 date5

Вопрос: как посчитать количество РАБОЧИХ часов:минут которые устройство находилось в ремонте?

Задача тривиальная и довольно распространенная, но у меня получился код листа на два. При этом если еще ввести выходные, обеденный перерыв, то код еще увеличивается в разы. Возможно есть более оригинальное решение.

Re: Как Посчитать кол-во рабочих часов

Добавлено: 07 янв 2007, 13:30
DrLance
Если работаешь с базой, напиши все в запросе.

Re: Как Посчитать кол-во рабочих часов

Добавлено: 07 янв 2007, 14:25
SergeyS
я сам недавно выполнял подобную задачу на SQL Server. Поэтому уточни используешь ли ты базу данных

Re: Как Посчитать кол-во рабочих часов

Добавлено: 07 янв 2007, 15:32
Snickbw
SergeyS писал(а):я сам недавно выполнял подобную задачу на SQL Server. Поэтому уточни используешь ли ты базу данных
Да. Все данные хранятся в БД. Подскажи код, если не трудно.

Re: Как Посчитать кол-во рабочих часов

Добавлено: 08 янв 2007, 08:13
SergeyS
Вот некоторый псевдокод

Код: Выделить всё

-- Таблица Заявки хранит информацию о времени ремонта
CREATE TABLE Заявки (Код INT, ДатаНачала DATETIME, ДатаКонца DATETIME)

/* Таблица Периоды хранит всю информацию о рабочих периодах в виде:
	"2006-01-11 08:00", "2006-01-11 12:00"
	"2006-01-11 13:00", "2006-01-11 17:00"
	12 и 13 числа января выходные, следовательно записей на эти дни нет
	"2006-01-14 08:00", "2006-01-14 12:00"
	"2006-01-14 13:00", "2006-01-14 17:00"
	"2006-01-15 08:00", "2006-01-15 12:00"
	"2006-01-15 13:00", "2006-01-15 17:00"
*/
CREATE TABLE Периоды (ДатаНачала DATETIME, ДатаКонца DATETIME)

SELECT SUM(DATEDIFF(hh, C.ДатаНачала, C.ДатаКонца)) AS Часы
FROM (
	SELECT
		CASE WHEN A.ДатаНачала BETWEEN B.ДатаНачала AND B.ДатаКонца THEN
			A.ДатаНачала ELSE B.ДатаНачала END AS ДатаНачала,
		CASE WHEN A.ДатаКонца BETWEEN B.ДатаНачала AND B.ДатаКонца THEN
			A.ДатаКонца ELSE B.ДатаКонца END AS ДатаКонца
	FROM Заявки A
	JOIN Периоды B ON B.ДатаНачала <= A.ДатаКонца AND B.ДатаКонца >= A.ДатаНачала
	WHERE A.Код = @КодЗаявки
) С
Возможно ведение таблицы Периоды выглядит не очень удобным, но на практике это крайне удобная вещь. Ведь здесь можно указать сокращённые рабочие дни, нестандартные праздники и т.д.

Мы в своей базе ведём подобную таблицу, все к ней привязываем (она у нас выглядит гораздо круче). Только наличие подобной таблицы избавляет от огромного количества проблем с анализом дат и периодов