目前,我正在根据开始日期(日期时间)和持续时间(天数)来计算完成日期,但我的计算并未考虑周末或假日。
所以,我的解决方案不正确。这只是一个起点。
我在那里阅读了一些文章,其中一种方法是创建一个巨大的日历表,其中包含未来50年的所有周末和假期。我想这个想法是根据日历表查询日期范围并减去周末和/或假期的数量。
问题是我正在处理的软件允许用户设置自己的项目日历。 考虑到软件允许用户管理多个项目,表格不会变得很大吗?
所以,我想我的问题是如何开始以及解决这个问题的可能方法是什么?
基本上,对于每个项目任务,我需要在给定START日期和DURATION的情况下计算任务完成日期,但要考虑周末和自定义日期(即假日)。
有什么想法吗?
BTW:我正在使用SQL Server 2005.
答案 0 :(得分:1)
创建一个包含[长时间]剩余时间的所有周末和假日的大日历,将其设置为仅选择。然后,每次创建新项目时,将所需的日期复制到日历中,并复制到项目的日历中。
答案 1 :(得分:1)
我在那里阅读了一些文章,其中一种方法是创建一个巨大的日历表,其中包含未来50年的所有周末和假期。我想这个想法是根据日历表查询日期范围并减去周末和/或假期的数量。
这是因为有些假期不会一直在同一天。劳动节例如 - 九月的第一个星期一。它更容易和在数据库中占用较少的空间来存储每年的日期,而不是尝试编写规则来计算它。
其他考虑因素是周六/周日降落的假期 - 如果休息日将在周一或周五下降,那将是一个折腾。有些假期将是联邦政府,而其他假期则是当地的......
答案 2 :(得分:0)
假设您有一个名为AllDays的表,其中包含名为theDay和IsPublicHoliday的列。另外假设您的@@ DATEFIRST设置为1,因此您的周末是第1天和第7天。您想在@StartDate中找到@n天的日期。
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(day,num,@ StartDate)。您可以在不合格的日期列表中进行LEFT JOIN(当然应该编入索引)。
答案 3 :(得分:0)
@Stuart:是的,50天是一个类型= P.我的意思是50年。
@rexem: 确实如此。计算过于复杂且容易出错。
@David:创建一个只选的主日历表,然后复制每个项目所需的日期听起来是个好主意。
(原谅,我的推特般的回应,哈哈)
感谢您的回复!
答案 4 :(得分:0)
嗨,这是我解决它的问题:
首先我创建了一个日历表(tb_cal),其中包含两个字段date_day(smalldate),holiday(bit)
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
您可以通过传递参数(from,to)
来调用此函数SELECT user.fc_get_labor_days(my_date_from, my_date_to) as [days]
希望这有帮助
答案 5 :(得分:0)
在排除周末和假期后,使用以下代码获取下一个工作日期
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