2009-07-29 23 views
5

Tôi đang tạo bảng lịch cho kho của mình. Tôi sẽ sử dụng nó như một khóa ngoại cho tất cả các trường ngày tháng.Ngày Lao động Vs. Lễ Tạ Ơn

Mã được hiển thị bên dưới tạo bảng và điền vào bảng đó. Tôi đã có thể tìm ra cách để tìm Ngày Tưởng niệm (Thứ Hai cuối cùng của tháng Năm) và Ngày Lao Động (thứ Hai đầu tiên của tháng Chín).

SET NOCOUNT ON 

DROP Table dbo.Calendar 
GO 
Create Table dbo.Calendar 
(
    CalendarId    Integer NOT NULL, 
    DateValue    Date NOT NULL, 
    DayNumberOfWeek   Integer NOT NULL, 
    NameOfDay    VarChar (10) NOT NULL, 
    NameOfMonth    VarChar (10) NOT NULL, 
    WeekOfYear    Integer NOT NULL, 
    JulianDay    Integer NOT NULL, 
    USAIsBankHoliday  Bit  NOT NULL, 
    USADayName    VarChar (100) NULL, 
) 
ALTER TABLE dbo.Calendar ADD CONSTRAINT 
    DF_Calendar_USAIsBankHoliday DEFAULT 0 FOR USAIsBankHoliday 
GO 
ALTER TABLE dbo.Calendar ADD CONSTRAINT 
    DF_Calendar_USADayName DEFAULT '' FOR USADayName 
GO 

Declare @StartDate DateTime = '01/01/2000' 
Declare @EndDate DateTime = '01/01/2020' 

While @StartDate < @EndDate 
Begin 
    INSERT INTO dbo.Calendar 
    (
     CalendarId, 
     DateValue, 
     WeekOfYear, 
     DayNumberOfWeek, 
     NameOfDay, 
     NameOfMonth, 
     JulianDay 
    ) 
    Values 
    (
     YEAR (@StartDate) * 10000 + MONTH (@StartDate) * 100 + Day (@StartDate), --CalendarId 
     @StartDate,     -- DateValue 
     DATEPART (ww, @StartDate), -- WeekOfYear 
     DATEPART (dw, @StartDate), -- DayNumberOfWeek 
     DATENAME (dw, @StartDate), -- NameOfDay 
     DATENAME (M, @StartDate), -- NameOfMonth 
     DATEPART (dy, @StartDate) -- JulianDay 
    ) 

    Set @StartDate += 1 
End 

--=========================== Weekends 
-- saturday and sunday 
UPDATE dbo.Calendar SET USAIsBankHoliday = 1, USADayName += 'Weekend, ' WHERE DayNumberOfWeek IN (1, 7) 


--=========================== Bank Holidays 
-- new years day 
UPDATE dbo.Calendar SET USAIsBankHoliday = 1, USADayName += 'New Year''s Day, ' WHERE (CalendarId % 2000) IN (101) 

-- memorial day (last Monday in May) 
UPDATE dbo.Calendar 
SET USAIsBankHoliday = 1, 
    USADayName += 'Memorial Day, ' 
WHERE 1=1 
AND CalendarId IN 
    (
     SELECT MAX (CalendarId) 
     FROM dbo.Calendar 
     WHERE MONTH (DateValue) = 5 
     AND DATEPART (DW, DateValue)=2 
     GROUP BY YEAR (datevalue) 
    ) 

-- independence day 
UPDATE dbo.Calendar SET USAIsBankHoliday = 1, USADayName += 'Independence Day, ' WHERE (CalendarId % 2000) IN (704) 

-- labor day (first Monday in September) 
UPDATE dbo.Calendar 
SET USAIsBankHoliday = 1, 
    USADayName += 'Labor Day, ' 
WHERE 1=1 
AND CalendarId IN 
    (
     SELECT MIN (CalendarId) 
     FROM dbo.Calendar 
     WHERE MONTH (DateValue) = 9 
     AND DATEPART (DW, DateValue)=2 
     GROUP BY YEAR (datevalue) 
    ) 

-- thanksgiving day (fourth Thursday in November) 
UPDATE dbo.Calendar 
SET USAIsBankHoliday = 1, 
    USADayName += 'Thanksgiving Day, ' 
WHERE 1=1 
AND CalendarId IN 
    (
     SELECT Max (CalendarId) 
     FROM dbo.Calendar 
     WHERE MONTH (DateValue) = 11 
     AND DATEPART (DW, DateValue)=5 
     GROUP BY YEAR (datevalue) 
    ) 

-- christmas 
UPDATE dbo.Calendar SET USAIsBankHoliday = 1, USADayName += 'Christmas Day, ' WHERE (CalendarId % 2000) IN (1225) 

--=========================== Other named days 
-- new years eve 
UPDATE dbo.Calendar SET USADayName += 'New Year''s Eve, ' WHERE (CalendarId % 2000) IN (1231) 

-- christmas eve 
UPDATE dbo.Calendar SET USADayName += 'Christmas Eve, ' WHERE (CalendarId % 2000) IN (1224) 

-- boxing day 
UPDATE dbo.Calendar SET USADayName += 'Boxing Day, ' WHERE (CalendarId % 2000) IN (1226) 

--=========================== Remove trailing comma 
UPDATE dbo.Calendar SET USADayName = SubString (USADayName, 1, LEN (USADayName) -1) WHERE LEN (USADayName) > 2 

SELECT * FROM dbo.Calendar 

Tôi bị bối rối khi tìm ra ngày Lễ tạ ơn (Thứ năm tuần cuối cùng của tháng 11).

Edit: Correction dựa trên nhận xét của John Sauer

Lễ Tạ Ơn là thứ năm thứ tư của tháng mười một. Tuy nhiên, khi kiểm tra vài năm, tôi thấy rằng nó đã trở thành thứ Năm của tuần cuối cùng của tháng 11 năm

+0

Rời khỏi. Làm cho gà tây hạnh phúc. – balpha

+2

Sự bắt đầu của lễ Ramadan cũng là một thách thức. – Smandoli

+0

Và sau đó, có Thứ Sáu Tuần Thánh và Lễ Phục Sinh ... – RobH

Trả lời

16

Tôi bị bối rối khi tìm ra ngày Lễ Tạ ơn (Thứ năm tuần cuối cùng của tháng 11).

cuối thứ bảy của tháng mười một - 2

6

Đi ngày thứ Bảy cuối cùng của tháng mười một, và trừ hai ngày;)

3
WITH cal AS 
     (
     SELECT CAST('2009-30-11' AS DATETIME) AS cdate 
     UNION ALL 
     SELECT DATEADD(day, -1, cdate) 
     FROM cal 
     WHERE cdate >= '2009-01-11' 
     ) 
SELECT TOP 1 DATEADD(day, -2, cdate) 
FROM cal 
WHERE DATEPART(weekday, cdate) = 6 

Đối với các thuật toán phức tạp, đôi khi tốt hơn để tìm một ngày phù hợp từ một bộ hơn là cố gắng xây dựng một công thức có giá trị đơn cực lớn.

Xem bài viết này trong blog của tôi để xem chi tiết hơn:

1
declare @thedate datetime 
set @thedate = '11/24/2011' 

select 1 
where datepart(dw, @thedate) = 5 and datepart(m, @thedate) = 11 AND (datepart(dd, @thedate) - 21) between 0 and 6 

là ngày một ngày thứ năm trong tháng mười một và là có ít hơn một tuần còn lại.

Các vấn đề liên quan