How do I determine a public holiday in Sql server?

前端 未结 24 1842
慢半拍i
慢半拍i 2020-12-05 14:40

I have an application written in c# that cannot run on a public holiday or a weekend. I\'ve looked around a bit and haven\'t found anywhere (official) that provides all the

相关标签:
24条回答
  • 2020-12-05 15:15

    I just gather information over the internet and I come with this easy way to calculate the US Bank Holidays.


    US Bank Holidays

    ===========================

    DECLARE @Year char(4)
    , @Date datetime
    , @Holiday datetime
    
    SET @Year = 2010
    
    ---- New Years Day
    SET @Date=CONVERT( datetime, CONVERT(varchar, YEAR( @Year ) )+'-01-01' ) 
    IF DATENAME( dw, @Date ) = 'Saturday'
        SET @Date=@Date-1
    ELSE IF DATENAME( dw, @Date ) = 'Sunday'
        SET @Date=@Date+1
    SELECT @Date [New Years Day], DATENAME( dw, @Date ) [DayOfWeek]
    
    ---- Martin L King's Birthday ( 3rd Monday in January )
    SET @Date = CONVERT( datetime, CONVERT(varchar, YEAR( @Year ) )+'-01-01' ) 
    SET @Holiday = DATEADD( wk, DATEDIFF( wk, 0, dateadd( dd, 18-datepart( day, @Date ), @Date ) ), 0 ) -- 3rd Monday of the Month
    SELECT @Holiday [Martin L King's Birthday], DATENAME( dw, @Holiday ) [DayOfWeek]
    
    ---- President’s Day ( 3rd Monday in February )
    SET @Date = CONVERT( datetime, CONVERT(varchar, YEAR( @Year ) )+'-02-01' ) 
    SET @Holiday = DATEADD( wk, DATEDIFF( wk, 0, dateadd( dd, 18-datepart( day, @Date ), @Date ) ), 0 ) -- 3rd Monday of the Month
    SELECT @Holiday [President’s Day], DATENAME( dw, @Holiday ) [DayOfWeek]
    
    ---- Memorial Day ( Last Monday in May )
    SET @Date = CONVERT( datetime, CONVERT(varchar, YEAR( @Year ) )+'-05-01' ) 
    SET @Holiday = DATEADD( wk, DATEDIFF( wk, 0, dateadd( dd, 30-datepart( day, @Date ), @Date ) ), 0 ) -- 5th Monday of the Month
    SELECT @Holiday [Memorial Day], DATENAME( dw, @Holiday ) [DayOfWeek]
    
    ---- Independence Day ( July 4 )
    SET @Date=CONVERT( datetime, CONVERT(varchar, YEAR( @Year ) )+'-07-04' ) 
    IF DATENAME( dw, @Date ) = 'Saturday'
        SET @Date=@Date-1
    ELSE IF DATENAME( dw, @Date ) = 'Sunday'
        SET @Date=@Date+1
    SELECT @Date [Independence Day], DATENAME( dw, @Date ) [DayOfWeek]
    
    ---- Labor Day ( 1st Monday in September )
    SET @Date = CONVERT( datetime, CONVERT(varchar, YEAR( @Year ) )+'-09-01' ) 
    SET @Holiday = DATEADD( wk, DATEDIFF( wk, 0, dateadd( dd, 6-datepart( day, @Date ), @Date ) ), 0 ) -- 1st Monday of the Month
    SELECT @Holiday [Labor Day], DATENAME( dw, @Holiday ) [DayOfWeek]
    
    ---- Columbus Day ( 2nd Monday in October )
    SET @Date = CONVERT( datetime, CONVERT(varchar, YEAR( @Year ) )+'-10-01' ) 
    SET @Holiday = DATEADD( wk, DATEDIFF( wk, 0, dateadd( dd, 12-datepart( day, @Date ), @Date ) ), 0 ) -- 2nd Monday of the Month
    SELECT @Holiday [Columbus Day], DATENAME( dw, @Holiday ) [DayOfWeek]
    
    ---- Veteran’s Day ( November 11 )
    SET @Date=CONVERT( datetime, CONVERT(varchar, YEAR( @Year ) )+'-11-11' ) 
    IF DATENAME( dw, @Date ) = 'Saturday'
        SET @Date=@Date-1
    ELSE IF DATENAME( dw, @Date ) = 'Sunday'
        SET @Date=@Date+1
    SELECT @Date [Veteran’s Day], DATENAME( dw, @Date ) [DayOfWeek]
    
    ---- Thanksgiving Day ( 4th Thursday in November )
    SET @Date = CONVERT( datetime, CONVERT(varchar, YEAR( @Year ) )+'-11-04' ) 
    SET @Holiday = DATEADD( wk, DATEDIFF( wk, 0, dateadd( dd, 22-datepart( day, @Date ), @Date ) ), 0 )+3 -- 4th Thursday of the Month
    SELECT @Holiday [Thanksgiving Day], DATENAME( dw, @Holiday ) [DayOfWeek]
    
    ---- Christmas Day ( December 25 )
    SET @Date=CONVERT( datetime, CONVERT(varchar, YEAR( @Year ) )+'-12-25' ) 
    IF DATENAME( dw, @Date ) = 'Saturday'
        SET @Date=@Date-1
    ELSE IF DATENAME( dw, @Date ) = 'Sunday'
        SET @Date=@Date+1
    SELECT @Date [Christmas Day], DATENAME( dw, @Date ) [DayOfWeek]
    
    ---- New Years Eve Day
    SET @Date=CONVERT( datetime, CONVERT(varchar, YEAR( @Year ) )+'-12-31' ) 
    IF DATENAME( dw, @Date ) = 'Saturday'
        SET @Date=@Date-1
    ELSE IF DATENAME( dw, @Date ) = 'Sunday'
        SET @Date=@Date+1
    SELECT @Date [New Years Day], DATENAME( dw, @Date ) [DayOfWeek]
    
    0 讨论(0)
  • 2020-12-05 15:15

    You are going to need to maintain a holiday table for this. For proper internationalization, you even need to maintain which days are weekend days for this since even that is not universal. Likewise, you might need to maintain holidays by locale so your program knows the users in London have the day off but the users in Turkey do not.

    This should be completely configurable by the user. For all you know, the company owner's birthday might be a "standard" day off. Try to find that holiday on the web.

    Lastly, you do not want to store 50 years worth of holiday data. It will only be inaccurate and potentially slow all your code down.

    0 讨论(0)
  • 2020-12-05 15:15

    google calendar public hollydays Maybe you could retrive your country/region data with google Calendar web service.

    0 讨论(0)
  • 2020-12-05 15:17

    In our applications we have it part of the user configuration. There is a place for users to set what they consider public/bank holidays for as far into the future as they want. For ease of use there is the ability to copy them by date from previous years. This also allows them to set 'custom' public holdays, perhaps a day that the company treats as a holiday but is not natioanlly official...

    Programatically, however, there are absolutely no assumptions at all. It's effectively just a user maintained table of dates.

    (This includes the UK because, as stated above, some holidays vary and are not set in stone, and sometimes there are special one-off days.)

    0 讨论(0)
  • 2020-12-05 15:20

    There is a web service available for this --

    http://www.holidaywebservice.com/Holidays/servicesAvailable_HolidayService.aspx

    0 讨论(0)
  • 2020-12-05 15:20

    In some countries (i.e. in Poland) number of holidays deepens on Easter.

    At the end of this post you can find a code to calculate eater date and few holidays that depends on it.

    Non-movable holidays, that are i.e. January 1st, Christmas Holidays, Independence day etc. can be stored somewhere in table.

    Bear in mind that in number countries you have regions/states that can have additional public holidays, but to calculate all holidays for your country or region should be possible.

    In UK i.e. you have Bank holidays that have some rules you can use in your code. - First Monday of May - Last Monday of May - Last Monday of August etc.

    Please check this link for more details http://en.wikipedia.org/wiki/Public_holidays_in_the_United_Kingdom

    How to calculate Easter date in SQL:

    http://www.smart.net/~mmontes/nature1876.html

    http://ghiorzi.org/easterda.htm

    declare @a int
    declare @b int
    declare @c int
    declare @d int
    declare @e int
    declare @f int
    declare @g int
    declare @h int
    declare @i int
    declare @j int
    declare @k int
    declare @l int
    declare @m int
    declare @n int
    declare @Year int
    declare @Month int
    declare @Day int
    declare @EasterSunday datetime
    declare @EasterMonday datetime
    declare @Pentecost datetime
    declare @CorpusChristi datetime
    
    SET @Year = 2014
    
    SET @a = @Year%19;
    SET @b = @Year/100;
    SET @c = @Year%100;
    SET @d = @b/4;
    SET @e = @b%4;
    SET @f = @c/4;
    SET @g = @c%4;
    
    
       SET @h = (@b + 8)/25;
       SET @i = (@b - @h + 1)/3;
       SET @j = (19*@a + @b -  @d - @i + 15) % 30;
       SET @k = (32 + 2*@e + 2*@f - @j - @g) % 7;
       SET @m = (@a + 11*@j + 22*@k) / 451;
       SET @n = @j + @k - 7*@m + 114;
    
       SET @Month = @n/31;
       SET @Day = (@n % 31) + 1;
    
    --PRINT @Year
    --PRINT @Month
    --PRINT @Day
    
    SET @EasterSunday = dateadd(month,((@Year-1900)*12)+@Month-1,@Day-1)
    SET @EasterMonday = dateadd(day,1,@EasterSunday)
    SET @Pentecost = dateadd(day,49,@EasterSunday)
    SET @CorpusChristi = dateadd(day,60,@EasterSunday)
    
    
    PRINT 'Easter Sunday: ' + CONVERT(VARCHAR, @EasterSunday,120) + ' [' + DATENAME(dw, @EasterSunday) + ']'
    PRINT ''
    
    PRINT 'Easter Monday: ' + CONVERT(VARCHAR, @EasterMonday,120) + ' [' + DATENAME(dw, @EasterMonday) + ']'
    PRINT ''
    
    PRINT 'Pentecost: ' + CONVERT(VARCHAR, @Pentecost,120) + ' [' + DATENAME(dw, @Pentecost) + ']'
    PRINT ''
    
    PRINT 'CorpusChristi: ' + CONVERT(VARCHAR, @CorpusChristi,120) + ' [' + DATENAME(dw, @CorpusChristi) + ']'
    PRINT ''
    
    0 讨论(0)
提交回复
热议问题