Weblog @ rebex.cz

Weblogy na webu Rebexu
Welcome to Weblog @ rebex.cz Sign in | Help
in Search

Weblog @ Rebex.cz :: Honza Šotola

nepravidelné poznámky .NET vývojáře

Výpočet počtu pracovních dnů v daném období

V tomto článku naleznete implementaci algoritmu pro zjištění počtu pondělků až pátků v období mezi dvěma zadanými daty.
Realizováno jako uživatelem definovaná funkce v T-SQL pro MS SQL Server 2005 (a asi i nižší).

Algoritmus jsem použil pro tvorbu sestav v jednom systému pro vykazování práce v jedné specifické státní instituci.

Pro zadané období vrací počet pracovních dnů (pondělků-pátků, bez ohledu na svátky v pracovní dny).
Počáteční i koncový den intervalu se také počítá.
Pro nesprávné vstupní údaje (prázdné či překřížené meze) vrací NULL.

POZOR - funkce ke svému chodu využívá ještě funkci ConvertDayOfWeek, kterou popisuji v jiném článku.

Příklady volání:

-- středa 7.11.2007 - úterý 13.11.2007
PRINT
dbo.WorkingDays('2007-11-07', '2007-11-13')
-- vrací 5 dnů

Imlementace:

--------------------------------------------------------
-- WorkingDays
--------------------------------------------------------
-- Returns count of working days (mondays-fridays, regardles holidays)
-- within given interval (including starting and ending days of the interval)
-- if the input arguments are invalid (empty or crossed), returns null
--
CREATE FUNCTION dbo.WorkingDays
	(
		@dt_from datetime, @dt_to datetime
	)
RETURNS int
AS
	BEGIN
		-- check input arguments
		IF @dt_from IS NULL OR @dt_to IS NULL
			RETURN NULL
		IF @dt_from > @dt_to 
			RETURN NULL

		-- === first count number of working days of starting and ending uncomplete weeks ===
		DECLARE @starting_week_days int
		
		-- weekdays in starting uncomplete week	
		--  the algorithm works with week starting on Monday so we have to convert the day of week to it
		DECLARE @starting_day int
		SET @starting_day = dbo.ConvertDayOfWeek(DatePart(weekday, @dt_from), @@DATEFIRST, 1)	-- 1=Monday
		SET @starting_week_days = 6 - @starting_day
		IF @starting_week_days < 0 SET @starting_week_days = 0

		-- weekdays in ending uncomplete week	
		--  the algorithm works with week starting on Monday so we have to convert the day of week to it
		DECLARE @ending_day int
		SET @ending_day = dbo.ConvertDayOfWeek(DatePart(weekday, @dt_to), @@DATEFIRST, 1)	-- 1=Monday
		DECLARE @ending_week_days int
		SET @ending_week_days = @ending_day
		IF @ending_week_days >= 6 SET @ending_week_days = 5


		-- === then count weekdays of middle complete weeks ===
		DECLARE @total_days int
		DECLARE @total_weekdays int
		SET @total_days = datediff(day, @dt_from, @dt_to) + 1
		-- the algorithm differs whether the starting and ending week aren't the same
		IF (@starting_day <= @ending_day AND @total_days <= 7)
			SET @total_weekdays = CASE WHEN @ending_day > 5 THEN 5 ELSE @ending_day END - @starting_day + 1
		ELSE	-- more than one week
			SET @total_weekdays =
					@ending_week_days 
					+ @starting_week_days 
					-- the result within parenthes is count of days of completw weeks so it is always divisible by 7
					+ (@total_days - (7 - @starting_day + 1) - @ending_day) * 5 / 7		
		
		-- === return result ===
		RETURN @total_weekdays
	END
GO
Published 7. listopadu 2007 6:23 by honzas
Filed under:

Comment Notification

If you would like to receive an email when updates are made to this post, please register here

Subscribe to this post's comments using RSS

Comments

 

tomas said:

Jako .Net programátora mě napadá dotaz: Nebylo by na tohle jednodušší použít hostovaný .NET na SQL Server-u 2005 ?

listopadu 7, 2007 16:45
 

honzas said:

No, implementačně by to jistě jednodušší bylo. Ale zase by bylo více práce s deploymentem. A někteří konzervativní vedoucí projektů či db admini nemají CLR v SQL rádi... Což byl můj případ, když jsem ty funkce psal.

listopadu 29, 2007 19:23

Leave a Comment

(required) 
(optional)
(required) 
Submit
Powered by Community Server (Personal Edition), by Telligent Systems