Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Работа с датами с учетом рабочего времени  [new]
Ganj
Member

Откуда:
Сообщений: 38
Доброго времени суток!

Есть следующая задача: есть текущая дата и некоторая дата date. нужно узнать разницу между ними в минутах, но нужно учитывать, что в разницу нужно брать только рабочее время (с 9:00 до 18:00).

Например, разница между датами 03.08.2009 17:40 и 04.08.2009 09:20 равна 40-ка минутам.

Выходные тоже не нужно учитывать.
Спасибо!
4 авг 09, 13:25    [7495382]     Ответить | Цитировать Сообщить модератору
 Re: Работа с датами с учетом рабочего времени  [new]
Ramin Hashimzade
Member

Откуда: Азербайджан, Баку
Сообщений: 9979
Блог
НАПИСАТЬ МАЛЕНКУ ФУНКЦИЮ который принимает 2 даты внутри изменяет часы второй даты на 18:00 и возврашает разницу... усе

----
www.hramin.jino-net.ru
Картинка с другого сайта.
4 авг 09, 13:27    [7495394]     Ответить | Цитировать Сообщить модератору
 Re: Работа с датами с учетом рабочего времени  [new]
iap
Member

Откуда: Москва
Сообщений: 46975
Ganj
Доброго времени суток!

Есть следующая задача: есть текущая дата и некоторая дата date. нужно узнать разницу между ними в минутах, но нужно учитывать, что в разницу нужно брать только рабочее время (с 9:00 до 18:00).

Например, разница между датами 03.08.2009 17:40 и 04.08.2009 09:20 равна 40-ка минутам.

Выходные тоже не нужно учитывать.
Спасибо!
Что такое "выходные"?
Что значит "Выходные тоже не нужно учитывать."?
То есть считать их на общих основаниях или, наоборот, отбрасывать?
Как быть с праздниками и перенесёнными выходными?
Выходные у некоторых бывают в понедельник, а кто-то работает сутки-через-трое...
4 авг 09, 13:30    [7495426]     Ответить | Цитировать Сообщить модератору
 Re: Работа с датами с учетом рабочего времени  [new]
Ganj
Member

Откуда:
Сообщений: 38
Выходные нужно отбрасывать. Как выходные считать нужно только субботу и воскресенье.
4 авг 09, 13:36    [7495482]     Ответить | Цитировать Сообщить модератору
 Re: Работа с датами с учетом рабочего времени  [new]
Алексей2003
Member

Откуда: Москва
Сообщений: 5645
без использования дополнительной таблички, точно просуммировать рабочее время нельзя.

для спящего время бодрствования равносильно сну
4 авг 09, 13:50    [7495623]     Ответить | Цитировать Сообщить модератору
 Re: Работа с датами с учетом рабочего времени  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6723
SET DATEFIRST 1	-- Неделя от панидёрнига
DECLARE	@Exception	TABLE (
	[Date]	SmallDateTime	PRIMARY KEY	-- Date
)INSERT	@Exception	SELECT '20081231'	-- Празднеги:
UNION ALL		SELECT '20090101'
UNION ALL		SELECT '20090102'
UNION ALL		SELECT '20090105'
UNION ALL		SELECT '20090106'
UNION ALL		SELECT '20090107'
UNION ALL		SELECT '20090108'
UNION ALL		SELECT '20090109'
UNION ALL		SELECT '20090117'	-- Отрабатываем '20090108'
UNION ALL		SELECT '20090124'	-- Отрабатываем '20090109'

DECLARE	 @Begin		SmallDateTime	-- Time	-- Время начала    рабочего дня
	,@End		SmallDateTime	-- Time	-- Время окончания рабочего дня
	,@LunchBegin	SmallDateTime	-- Time	-- Время начала    обеда
	,@LunchEnd	SmallDateTime	-- Time	-- Время окончания обеда
	,@From		SmallDateTime	-- От
	,@To		SmallDateTime	-- До
SELECT	 @Begin		= '08:15'	-- '19000101' = 0
	,@End		= '17:15'
	,@LunchBegin	= '13:00'
	,@LunchEnd	= '14:00'
	,@From		= '20081229 13:50'
	,@To		= '20090124 08:40'
--------------------------------------------------------------------------------
;WITH Exception AS (
	SELECT	 Date
		,CASE	WHEN DatePart(WeekDay,Date) < 6
			THEN  1	-- Выходной в рабочий день, т.е. праздник
			ELSE -1	-- Рабочий день в выходной, т.е. отработка
			END	AS Exception
	FROM	@Exception
)SELECT	 (DateDiff(Week
		,DateAdd(Day,1-WeekDay.[From],Day.[From])
		,DateAdd(Day,1-WeekDay.[To]  ,Day.[To]  )) * 5		-- Полные рабочие   недели
	- CASE WHEN WeekDay.[From] > 6 THEN 6 ELSE WeekDay.[From] END	-- Дней в первой    неделе
	+ CASE WHEN WeekDay.[To]   > 6 THEN 6 ELSE WeekDay.[To]   END	-- Дней в последней неделе
	- Exception.Days)						-- Дней, исключений
	*(DateDiff(Minute,@Begin,@End) - Day.LunchTime)			-- Минут в рабочем   дне, за вычетом обеда
	- DateDiff(Minute,@Begin,Day.[Begin]) * ExceptionDay.[From]	-- Минут в первом    дне
	+ DateDiff(Minute,@Begin,Day.[End]  ) * ExceptionDay.[To]	-- Минут в последнем дне
FROM  (	SELECT	 Time.Lunch					AS LunchTime
		,DateAdd(Day, DateDiff(Day,0,@From),0)		AS [From]
		,DateAdd(Day, DateDiff(Day,0,@To  ),0)		AS [To]
		,CASE	WHEN Time.[Begin] < @Begin	THEN @Begin
			WHEN Time.[Begin] > @End	THEN DateAdd(Minute,-Time.Lunch,@End)		-- Смещаем на время обеда
			WHEN Time.[Begin] < @LunchBegin	THEN Time.[Begin]
			WHEN Time.[Begin] > @LunchEnd	THEN DateAdd(Minute,-Time.Lunch,Time.[Begin])	-- Смещаем на время обеда
			ELSE @LunchBegin		END	AS [Begin]
		,CASE	WHEN Time.[End]   < @Begin	THEN @Begin
			WHEN Time.[End]   > @End	THEN DateAdd(Minute,-Time.Lunch,@End)
			WHEN Time.[End]   < @LunchBegin	THEN Time.[End]
			WHEN Time.[End]   > @LunchEnd	THEN DateAdd(Minute,-Time.Lunch,Time.[End]  )
			ELSE @LunchBegin		END	AS [End]
	FROM  (	SELECT	 DateDiff(Minute,@LunchBegin,@LunchEnd)		AS Lunch
			,DateAdd(Day,-DateDiff(Day,0,@From),@From)	AS [Begin]
			,DateAdd(Day,-DateDiff(Day,0,@To  ),@To  )	AS [End]
		) Time
	) Day		CROSS APPLY (
	SELECT	 DatePart(WeekDay,Day.[From]) AS [From]
		,DatePart(WeekDay,Day.[To]  ) AS [To]
	) WeekDay	CROSS APPLY (
	SELECT	IsNull(Sum(Exception),0) AS Days
	FROM	Exception
	WHERE	    [Date] >= Day.[From]
		AND [Date] <  Day.[To]
	) Exception	CROSS APPLY (
	SELECT	 IsNull((SELECT (1-Exception)/2 FROM Exception WHERE [Date] = Day.[From]),CASE WHEN WeekDay.[From] < 6 THEN 1 ELSE 0 END) AS [From]
		,IsNull((SELECT (1-Exception)/2 FROM Exception WHERE [Date] = Day.[To]  ),CASE WHEN WeekDay.[To]   < 6 THEN 1 ELSE 0 END) AS [To]
	) ExceptionDay
5 авг 09, 03:21    [7498209]     Ответить | Цитировать Сообщить модератору
 Re: Работа с датами с учетом рабочего времени  [new]
guest9788979
Guest
Если всё же не заморачиваться с праздниками...

set nocount on
declare @dt datetime, @cnt int
set @cnt = 30
set @dt = getdate()
while @cnt > 0 begin
	set datefirst 1; print DATENAME(dw, @dt) + ', @@datefirst=' + cast(@@datefirst as varchar(1)) + ', isWeekend=' + case (DATEPART(dw, @dt) + @@datefirst - 2)%7+1 when 6 then '1' when 7 then '1' else '0' end
	set datefirst 2; print DATENAME(dw, @dt) + ', @@datefirst=' + cast(@@datefirst as varchar(1)) + ', isWeekend=' + case (DATEPART(dw, @dt) + @@datefirst - 2)%7+1 when 6 then '1' when 7 then '1' else '0' end
	set datefirst 3; print DATENAME(dw, @dt) + ', @@datefirst=' + cast(@@datefirst as varchar(1)) + ', isWeekend=' + case (DATEPART(dw, @dt) + @@datefirst - 2)%7+1 when 6 then '1' when 7 then '1' else '0' end
	set datefirst 4; print DATENAME(dw, @dt) + ', @@datefirst=' + cast(@@datefirst as varchar(1)) + ', isWeekend=' + case (DATEPART(dw, @dt) + @@datefirst - 2)%7+1 when 6 then '1' when 7 then '1' else '0' end
	set datefirst 5; print DATENAME(dw, @dt) + ', @@datefirst=' + cast(@@datefirst as varchar(1)) + ', isWeekend=' + case (DATEPART(dw, @dt) + @@datefirst - 2)%7+1 when 6 then '1' when 7 then '1' else '0' end
	set datefirst 6; print DATENAME(dw, @dt) + ', @@datefirst=' + cast(@@datefirst as varchar(1)) + ', isWeekend=' + case (DATEPART(dw, @dt) + @@datefirst - 2)%7+1 when 6 then '1' when 7 then '1' else '0' end
	set datefirst 7; print DATENAME(dw, @dt) + ', @@datefirst=' + cast(@@datefirst as varchar(1)) + ', isWeekend=' + case (DATEPART(dw, @dt) + @@datefirst - 2)%7+1 when 6 then '1' when 7 then '1' else '0' end
	set @dt = dateadd(day, -1, @dt)
	set @cnt = @cnt - 1
end
9 сен 09, 16:47    [7638222]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить