2009-10-22 3 views
3

В настоящее время я рассчитываю дату окончания в зависимости от даты начала (DateTime) и продолжительности (количество дней), но мои расчеты не учитывают выходные или праздничные дни ,Исключить выходные и пользовательские дни (например, Праздники) с даты расчета

Итак, мое решение неверно. Это была всего лишь отправная точка.

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

Проблема в том, что программное обеспечение, над которым я работаю, позволяет пользователям устанавливать свой собственный календарь проектов. Разве таблица не станет большой, чтобы поддерживать, учитывая, что программное обеспечение позволяет пользователям управлять несколькими проектами?

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

В принципе, для каждой проектной задачи мне нужно рассчитать дату завершения задачи с датой начала и продолжительностью дня, но с учетом выходных и пользовательских дней (например, праздников).

Любые идеи?

BTW: Я использую SQL Server 2005.

+1

Какого СУБД? (SQL Server? Oracle?) – SLaks

+0

50 дней? Это может быть опечатка? Большинство таблиц календаря должны иметь данные в течение многих лет. –

+0

Только что отредактированный от дней до лет –

ответ

1

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

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

Другие соображения - это праздники, которые приземляются на СБ/ВС - это тоссад, если выходной день выпадет в понедельник или пятницу. И некоторые праздники будут федеральными, а другие - местными ...

+0

D'oh ... не получил моего ответа до тех пор, пока это не было принято. –

+0

Пасха не так уж плоха, потому что вы можете найти формулу для нее. Большая проблема заключается в добавлении лишних дней, например, когда в 2002 году у Великобритании был дополнительный общественный праздник для Jubliee, или Австралия провела дополнительный государственный праздник для начала Олимпийских игр в Сиднее в 2000 году. Для этого вам действительно нужно таблицу с указанием выходных дней или поле «Исход» в таблице календаря. –

+0

Или рассмотрите такие вещи, как Рамадан, который меняется от года к году и с места на место. Это также * постановлено *, а не качелировано (хотя дата указа может быть оценена путем расчетов). http://j.mp/GKzaM –

1

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

0

Предположим, у вас есть таблица под названием AllDays, в которой есть столбцы, называемые «День» и «Испублика». Также предположим, что ваш @@ DATEFIRST установлен в 1, так что ваши выходные дни - дни 1 и 7. Вы хотите найти дату, которая находится @n дней с @StartDate.

WITH NumberedDays AS 
(
SELECT theDay, ROW_NUMBER() OVER (ORDER BY theDay) AS DayNum 
FROM AllDays 
WHERE DATEPART(dw, theDay) NOT IN (1,7) 
AND IsPublicHoliday = 0 
AND theDay > @StartDate 
) 
SELECT theDay 
FROM NumberedDays 
WHERE DayNum = @n 
; 

Если вы не имеете таблицу с именем Alldays, то вы можете легко использовать таблицу чисел, где theDay является DATEADD (день, Num, @ StartDate). Вы можете сделать LEFT JOIN в свой список недействительных дней (которые, конечно же, должны быть проиндексированы).

0

@Stuart: Да, 50 дней - это тип = P. Я имел в виду 50 лет.

@rexem: Это правда. Расчеты были бы слишком сложными и подвержен ошибкам.

@David: Создание главной таблицы календаря только для выбора, а затем копирование дат, необходимых мне для каждого проекта, звучит как отличная идея.

(пардон, мой твиттер-подобный ответ, ха-ха)

Спасибо большое за ответы!

+0

Вам понадобится rep, чтобы вы могли оставлять комментарии: p –

+0

Приношу свои извинения. Теперь я вижу кнопку комментария. Я не был полностью осведомлен о различии. благодаря! – Abe

0

Привет это ограда Я решаю его:

Сначала я создал таблицу календаря (tb_cal) с двумя полями date_day (smalldate), праздник (бит)

CREATE TABLE [user].[tb_cal](
[date_day] [smalldatetime] NULL, 
[holiday] [bit] NULL 
) ON [PRIMARY] 

то эта функция:

CREATE FUNCTION [user].[fc_get_labor_days] 
(@from datetime, @to datetime) 
RETURNS int 
AS 
BEGIN 
return ( 
select count(*) as total 
from tb_cal 
where datepart(dw, date_day) not in (1,7) 
and holiday <> 1 
and date_day > @from and date_day <= @to) 
END 

вы можете вызвать эту функцию, передав параметр (от, до)

SELECT user.fc_get_labor_days(my_date_from, my_date_to) as [days] 

Надеется, что это помогает

0

Используйте ниже кода, чтобы получить следующую дату wrking после исключая выходные и праздники

Declare @AddDay as integer = 3 
Declare @NextWorkingDate DateTime 
Declare @StartDate DateTime = Cast(getdate() as date) 

While @AddDay > 0 
    begin 

     Select @NextWorkingDate = @StartDate + @AddDay + 
     (datediff(wk, @StartDate, @StartDate+ @AddDay ) * 2) -- add weekend 

     --Exclude weekend 
     If datepart(dw,@NextWorkingDate) = 1 or datepart(dw,@NextWorkingDate) = 7 --Add 2 days if target date is either Saturday or Sunday 
      set @NextWorkingDate = @NextWorkingDate + 2 

     --Count no of holidays if falling within start date and nextwrking date 
     Select @AddDay = Count(*) from HolidayTable ST --Holiday list 
        where ST.OffDate between @StartDate+1 and @NextWorkingDate 
     Set @StartDate = @NextWorkingDate 
    End   

Select @NextWorkingDate 
Смежные вопросы