Как определить праздничный день на сервере Sql?

У меня есть приложение, написанное на c #, которое не может работать в праздничные дни или выходные. Я немного огляделся и не нашел нигде (официального), который обеспечил бы все праздничные дни для следующего, скажем, 50 лет.

Если я смогу их получить, я просто вставляю их в таблицу «Праздники» sql server и использую это. Однако я не могу найти эти данные нигде.

Кто-нибудь знает, есть ли у Sql-сервера какая-либо поддержка для государственных праздников или какой-то алгоритм для их работы? Или у кого-то есть официальное, из которого я могу вставить большую часть.

Благодарю.

EDIT: Для аргументов ради просто предположим, что нам нужны государственные праздники в Англии !!!!

Я просто собираю информацию через Интернет, и я прихожу с этим простым способом рассчитать Праздники Bank of Bank.


Праздники США

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

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 @[email protected] ELSE IF DATENAME( dw, @Date ) = 'Sunday' SET @[email protected]+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 @[email protected] ELSE IF DATENAME( dw, @Date ) = 'Sunday' SET @[email protected]+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 @[email protected] ELSE IF DATENAME( dw, @Date ) = 'Sunday' SET @[email protected]+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 @[email protected] ELSE IF DATENAME( dw, @Date ) = 'Sunday' SET @[email protected]+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 @[email protected] ELSE IF DATENAME( dw, @Date ) = 'Sunday' SET @[email protected]+1 SELECT @Date [New Years Day], DATENAME( dw, @Date ) [DayOfWeek] 

Насколько я знаю, нет никакого «официального» источника, и это действительно сильно зависит от языка. Вам придется управлять этим вручную. Хороший источник кажется:

http://en.wikipedia.org/wiki/List_of_holidays_by_country

Даже в этих условиях очень сложно управлять. Например, я живу в Бельгии, и в разных частях страны есть разные праздники. Например, правительственные работники имеют разные праздники по сравнению с остальной частью рабочей силы, и это соответствует одному языковому кодексу.

Разве это не государственный праздник, сильно зависящий от языка?

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

В наших приложениях мы являемся частью пользовательской конфигурации. Есть место, где пользователи могут устанавливать то, что они считают публичными / банковскими праздниками, как можно дальше. Для удобства использования есть возможность копировать их по дате с предыдущих лет. Это также позволяет им устанавливать «обычные» публичные торги, возможно, в тот день, когда компания относится к празднику, но не является официальным официальным …

Программно, однако, абсолютно никаких предположений нет. Это эффективная таблица дат, поддерживаемая пользователем.

(Это включает в себя Великобританию, потому что, как указано выше, некоторые праздники различаются и не устанавливаются в камне, а иногда есть особые разовые дни.)

Общественные праздники редко доступны в течение следующих 50 лет. В некоторых странах они известны в течение следующих нескольких лет, в некоторых странах – нет. Они также различаются по штатам и даже городам.

Для этого есть веб-сервис –

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

Вы можете использовать библиотеку Nager.Date для расчета государственных праздников. https://github.com/tinohager/Nager.Date

NuGet

 PM> install-package Nager.Date 

Пример:

 var publicHolidays = DateSystem.GetPublicHoliday(CountryCode.GB, 2017); foreach (var publicHoliday in publicHolidays) { var name = publicHoliday.LocalName; } 

Ahhh, праздничные календари. Проклятие любой жизни программиста инвестиционного банка. Боюсь, нет никакого способа сделать это, кроме сохранения собственного списка.

Вам нужно будет сохранить праздничный стол для этого. Для правильной интернационализации вам даже нужно поддерживать, какие дни дни для выходных, потому что даже это не универсально. Аналогичным образом, вам может потребоваться сохранить отпуск по языку, чтобы ваша программа знала, что у пользователей в Лондоне есть выходной, но у пользователей в Турции нет.

Это должно полностью настраиваться пользователем. Насколько вам известно, день рождения владельца компании может быть «стандартным» выходным днем. Попытайтесь найти этот праздник в Интернете.

Наконец, вы не хотите хранить данные о праздничных днях на 50 лет. Это будет неточно и потенциально замедлить весь ваш код.

Для многих из нас в США существует стандартный список деловых праздников, которые можно определить детерминистически.

Опираясь на код Vonpato, я собрал один оператор SQL, который использует функции Window (over (partition by ..)), новые в SQL Server 2008, чтобы определить N'th или последнее появление буднего дня в течение месяца ,

Это должно быть выполнено против «DimDate», стандартной таблицы измерений даты, например, найденной в хранилище данных. http://www.codeproject.com/Articles/647950/Create-and-Populate-Date-Dimension-for-Data-Wareho

 SELECT case when DayNameOfWeek = 'Saturday' then dateadd(day, -1, FullDate) when DayNameOfWeek = 'Sunday' then dateadd(day, 1, FullDate) else FullDate end as 'Holiday Date' FROM ( select row_number() over (partition by DayNameOfWeek, MonthOfYear, CalendarYear order by FullDate) as WeekdayOrdinal, count(*) over (partition by DayNameOfWeek, MonthOfYear, CalendarYear ) as MaxOrdinal, * from DimDate ) D WHERE (D.[MonthName] = 'January' and [DayOfMonth] = 1) /* New Years Day */ OR (D.[MonthName] = 'January' and DayNameOfWeek = 'Monday') and WeekdayOrdinal = 3 /* MLK Day */ OR (D.[MonthName] = 'February' and DayNameOfWeek = 'Monday') and WeekdayOrdinal = 3 /* President's Day */ OR (D.[MonthName] = 'May' and DayNameOfWeek = 'Monday') and WeekdayOrdinal = MaxOrdinal /* Memorial Day */ OR (D.[MonthName] = 'September' and DayNameOfWeek = 'Monday') and WeekdayOrdinal = 1 /* Labor Day */ OR (D.[MonthName] = 'October' and DayNameOfWeek = 'Monday') and WeekdayOrdinal = 2 /* Columbus Day */ OR (D.[MonthName] = 'November' and [DayOfMonth] = 11) /* Veteran's Day */ OR (D.[MonthName] = 'November' and DayNameOfWeek = 'Thursday') and WeekdayOrdinal = 4 /* Thanksgiving */ OR (D.[MonthName] = 'December' and [DayOfMonth] = 25 ) /* Christmas */ ORDER BY FullDate 

Если это просто Англия, тогда вы можете сами их выработать! Вам нужно будет получить надежный алгоритм определения Пасхи, но в противном случае я бы сказал, что вы можете сделать это через час.

Но вы имеете в виду только Англию или Великобританию? Поскольку в Шотландии разные праздники (Рождество, Хогманий и День Святого Андрея) и Северная Ирландия, Уэльс и, скорее всего, остров Мэн и Нормандские острова также должны торговаться по-разному.

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

Если вы действительно не можете самостоятельно управлять отпусками и не имеете пользователей, которым может быть предоставлена ​​ответственность, я бы посоветовал вернуться к вашему ограничению «не могу работать в общественных местах» и искать способы, которыми это может быть удален …

Для тех, у кого возникли проблемы с поиском последнего четверга ноября для Дня благодарения, я начинаю с поиска последнего дня месяца, затем использую цикл WHILE () до минус один день и проверяю имя файла, пока имя файла не появится в четверг:

 DECLARE @LastThursday DateTime = DATEADD(s,-1,DATEADD(mm,DATEDIFF(m,0,CONVERT(datetime,CONVERT(varchar,YEAR(GETDATE()))+'-11-01'))+1,0)) WHILE DATENAME(weekday,@LastThursday) <> 'Thursday' BEGIN SET @LastThursday = DATEADD(day,DATEDIFF(day,0,@LastThursday)-1,0) END SELECT @LastThursday 

В дополнение к тому, чтобы пользователь мог настроить, какие дни являются праздниками, было бы неплохо, если бы вы разрешили пользователю выбирать календарь для импорта или даже подписки. У iCalShare есть хороший список. Однако, вероятно, слишком много работы для функции, которая просто хороша.

Чтобы добавить то, что уже говорили другие люди, поставить свой собственный в таблице – единственный реальный способ сделать это. Классическим примером является дополнительный банковский праздник для золотого юбилея королевы. Это было объявлено только на пару лет вперед, и вы не могли за пятьдесят лет до этого.

В связи с этим существует ряд коммерческих услуг для надежного предоставления этих данных. Один из них – GoodBusinessDay.com, но у меня нет опыта с ним.

google calendar public hollydays Возможно, вы могли бы восстановить данные своей страны / региона с помощью веб-сервиса Google Calendar.

Нашел еще одну услугу для общемировых государственных праздников, предположительно используемых издателями календаря:

http://www.qppstudio.net/index.htm

Этот алгоритм может уменьшить количество ручной настройки в странах, которые соблюдают христианские праздники. Должно быть тривиально преобразовать в C #:

http://en.wikipedia.org/wiki/Computus#Anonymous_Gregorian_algorithm

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

Обратите внимание, что часто существуют различия между банковскими праздниками и обычными праздниками. Пример этого в Соединенных Штатах – это День независимости, где федеральное правительство признало праздник 3 июля, но Федеральный резервный банк Нью-Йорка был открыт.

2009 Федеральные праздники США

2009 Праздники Федерального резервного банка США

Если это помогает, у меня есть текстовый файл, в котором перечислены правила расчета банковских праздников, определенных для всех основных и мелких финансовых центров. Обычным способом определения этого является бизнес-центр, например, в Лондоне, Нью-Йорке, Франкфурте и т. Д., А не в стране. В качестве примера здесь приведены правила и объяснения для Лондона и некоторые другие. Если кто-то хочет, чтобы вся эта серия сообщила мне. Эта партия должна работать с 1990 по 2030 год как можно раньше. Очевидно, у него не будет никаких новых праздников, объявленных после того, как были собраны fles (2006 год, я думаю).

 /* * This file describes holiday calendars in the following way: * 1. The "n"th "dow" in the month "m", means the 3rd Wednesday in August = "ALWAYS,3,WED,AUG" * 2. The last etc "dow" in month "m", eg the last Monday in June = "LAST,MON,JUN" * 3. A set date which if on a Sat or Sun is taken on the Monday, eg 13th Aug. = "FWDFROM,13,AUG" * 4. A set date which if on a Sat is taken on Fri, if Sun on the Mon = "CLOSESTTO,13,AUG" * 5. A set date which, if on a Sat is unchanged, but if a Sun is taken on the Mon = "FWDFROMSUN,13,AUG" * 6. A set date which is unchanged if it happens to be on a weekend = "REMAINS,13,AUG" * 7. The first day on or after day "x" in month "m" eg 1st Monday on or after 16th Jan = "FIRSTAFTER,16,MON,JAN" * 8. A holiday which is a set number of days relative to Easter Sunday, eg Easter Monday = "EASTER,1" * 9. A holiday on one specified date only. eg 13th Aug 1997 = "ONEOFF,13,AUG,1997" * 10.A specific date which has been added but is not a holiday and must be removed. = "REMOVE,13,AUG,1997" * Note REMOVE only works on a date which is already in the calendar: you cannot remove a date which is yet to be added. * If there is any text after the definition of the holiday it will appear in the date calendar description, * eg you can have "FWDFROM,25,DEC,Christmas Day", if you wish. */ LON: HolidayCalendar { Config: String { FWDFROM,1,JAN,New Year's Day; EASTER,-2,Good Friday; EASTER,1,Easter Monday; ALWAYS,1,MON,MAY,Early May Bank Holiday; LAST,MON,MAY,Spring Bank Holiday; REMOVE,27,MAY,2002,Spring Bank Holiday; ONEOFF,3,JUN,2002,Spring Bank Holiday; ONEOFF,4,JUN,2002,Spring Bank Holiday; LAST,MON,AUG,Summer Bank Holiday; FWDFROM,25,DEC,Christmas; FWDFROM,26,DEC,Boxing Day; ONEOFF,31,DEC,1999,Millenium; } EndDate: 31-Dec-2030; Name: London; StartDate: 01-Jan-1990; Weekend: SAT,SUN,; } HKG: HolidayCalendar { Config: String { FWDFROM,1,JAN,New Year's Day; ONEOFF,16,FEB,1999,Chinese New Year; ONEOFF,17,FEB,1999,Chinese New Year; ONEOFF,18,FEB,1999,Chinese New Year; FWDFROM,5,FEB,2000,Chinese New Year; FWDFROM,6,FEB,2000,Chinese New Year; FWDFROM,7,FEB,2000,Chinese New Year; CLOSESTTO,5,APR,Ching Ming; EASTER,-2,Good Friday; EASTER,1,Easter Monday; FWDFROM,1,MAY,Labour Day; ONEOFF,18,JUN,1999,Dragon Boat Festival; FWDFROM,1,JUL,SAR Establishment Day; FWDFROM,1,OCT,National Day; FWDFROM,2,OCT,National Day; ONEOFF,25,SEP,1999,Mid Autumn Festival; ONEOFF,17,OCT,1999,Chung Yeung; FWDFROM,25,DEC,Christmas; FWDFROM,26,DEC,Boxing Day; ONEOFF,4,MAY,1998,May bank holiday; ONEOFF,25,MAY,1998,May bank holiday; ONEOFF,3,MAY,1999,May bank holiday; ONEOFF,31,MAY,1999,May bank holiday; ONEOFF,1,JUL,1997; ONEOFF,2,JUL,1997; } EndDate: 31-Dec-2030; Name: Hong Kong; StartDate: 01-Jan-1990; Weekend: SAT,SUN,; } MIL: HolidayCalendar { Config: String { FWDFROM,1,JAN,New Year's Day; REMAINS,6,JAN,Epiphany; REMAINS,25,APR,Liberation Day; REMAINS,1,MAY,May Day; REMAINS,15,AUG,Assumption; REMAINS,1,NOV,All Saint's; REMAINS,8,DEC,Immaculate Conception; EASTER,1,Easter Monday; FWDFROM,25,DEC,Christmas; FWDFROM,26,DEC,Boxing Day; } EndDate: 31-Dec-2030; Name: Milan; StartDate: 01-Jan-1990; Weekend: SAT,SUN,; } FFT: HolidayCalendar { Config: String { REMAINS,1,JAN,New Year's Day; EASTER,-2,Good Friday; EASTER,1,Easter Monday; REMAINS,1,MAY,Labour Day; EASTER,39,Ascension Day; EASTER,50,Whit Monday; EASTER,60,Corpus Christi; REMAINS,3,OCT,Day of German Unity; REMAINS,24,DEC,Christmas Eve; REMAINS,25,DEC,Christmas Day; REMAINS,26,DEC,Boxing Day; } EndDate: 31-Dec-2030; Name: Frankfurt; StartDate: 01-Jan-1990; Weekend: SAT,SUN,; } ZUR: HolidayCalendar { Config: String { REMAINS,1,JAN,New Year's Day; REMAINS,2,JAN,New Year's Holiday; EASTER,-2,Good Friday; EASTER,1,Easter Monday; EASTER,39,Ascension Day; EASTER,50,Whit Monday; REMAINS,1,AUG,August Bank Holiday; REMAINS,1,MAY, LABOUR DAY; REMAINS,25,DEC,Christmas; REMAINS,26,DEC,Boxing Day; } EndDate: 31-Dec-2030; Name: Zurich; StartDate: 01-Jan-1990; Weekend: SAT,SUN,; } NYK: HolidayCalendar { Config: String { REMAINS,1,JAN,New Year's Day; ALWAYS,3,MON,JAN,Martin Luther King; ALWAYS,3,MON,FEB,President's Day; LAST,MON,MAY,Memorial Day; CLOSESTTO,4,JUL,Independence Day; ALWAYS,1,MON,SEP,Labor Day; ALWAYS,2,MON,OCT,Columbus Day; REMAINS,11,NOV,Veteran's Day; ALWAYS,4,THU,NOV,Thanksgiving; FWDFROMSUN,25,DEC,Christmas Day; ONEOFF,12,NOV,2001,Veteran's Day; } EndDate: 31-Dec-2030; Name: New York; StartDate: 01-Jan-1990; Weekend: SAT,SUN,; } 

В некоторых странах (например, в Польше) количество праздников углубляется на Пасху.

В конце этого сообщения вы можете найти код для подсчета даты приема и нескольких праздников, которые зависят от него.

Недвижные праздники, то есть 1 января, Рождественские каникулы, День независимости и т. Д., Могут храниться где-то в таблице.

Имейте в виду, что в ряде стран у вас есть регионы / штаты, которые могут иметь дополнительные государственные праздники, но рассчитать все праздники для вашей страны или региона должны быть возможны.

В Великобритании, т. Е. У вас есть праздничные дни в Банке, которые имеют некоторые правила, которые вы можете использовать в своем коде. – Первый понедельник мая – последний понедельник мая – последний понедельник августа и т. Д.

Пожалуйста, проверьте эту ссылку для получения более подробной информации. http://en.wikipedia.org/wiki/Public_holidays_in_the_United_Kingdom

Как рассчитать дату Пасхи в 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)[email protected],@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 '' 

Давайте упростим это:


 case -- New Year's Day when DATEPART(MM, @DATE) = 1 and DATEPART(DD, @DATE) = 1 and DATEPART(DW, @DATE) in (2,3,4,5,6) then 'Y' when DATEPART(MM, @DATE) = 12 and DATEPART(DD, @DATE) = 31 and DATEPART(DW, @DATE) = 6 then 'Y' when DATEPART(MM, @DATE) = 1 and DATEPART(DD, @DATE) = 2 and DATEPART(DW, @DATE) = 2 then 'Y' -- Memorial Day (last Monday in May) when DATEPART(MM, @DATE) = 5 and DATEPART(DD, @DATE) between 25 and 31 and DATEPART(DW, @DATE) = 2 then 'Y' -- Independence Day when DATEPART(MM, @DATE) = 7 and DATEPART(DD, @DATE) = 4 and DATEPART(DW, @DATE) in (2,3,4,5,6) then 'Y' when DATEPART(MM, @DATE) = 7 and DATEPART(DD, @DATE) = 3 and DATEPART(DW, @DATE) = 6 then 'Y' when DATEPART(MM, @DATE) = 7 and DATEPART(DD, @DATE) = 5 and DATEPART(DW, @DATE) = 2 then 'Y' -- Labor Day (first Monday in September) when DATEPART(MM, @DATE) = 9 and DATEPART(DD, @DATE) between 1 and 7 and DATEPART(DW, @DATE) = 2 then 'Y' -- Thanksgiving Day (fourth Thursday in November) when DATEPART(MM, @DATE) = 11 and DATEPART(DD, @DATE) between 22 and 28 and DATEPART(DW, @DATE) = 5 then 'Y' -- Black Friday (day after Thanksgiving) when DATEPART(MM, @DATE) = 11 and DATEPART(DD, @DATE) between 23 and 29 and DATEPART(DW, @DATE) = 6 then 'Y' -- Christmas Day when DATEPART(MM, @DATE) = 12 and DATEPART(DD, @DATE) = 25 and DATEPART(DW, @DATE) in (2,3,4,5,6) then 'Y' when DATEPART(MM, @DATE) = 12 and DATEPART(DD, @DATE) = 24 and DATEPART(DW, @DATE) = 6 then 'Y' when DATEPART(MM, @DATE) = 12 and DATEPART(DD, @DATE) = 26 and DATEPART(DW, @DATE) = 2 then 'Y' else 'N' end 

Банковские каникулы в Великобритании в основном вычислимы, но определенно не все можно вычислить.

Правительство Великобритании предоставляет API ( https://www.gov.uk/bank-holidays.json ), который дает вам эту информацию.

Я нахожу эту тему странной. После попытки найти и написать сложные функции в MS, PHP или в этом случае на языке SQL я пришел к выводу, что это бессмысленное упражнение. Код, который я закончил, содержит более 2000 символов и занимает несколько часов, чтобы получить право и отладить. Если вы думаете об этом, вам нужно всего лишь написать 7 цифр, обозначающих день 1-365 для каждого праздника и строку на каждый год в течение следующих 100 лет. Вам нужно только загрузить эти годы или в следующие годы. Поэтому держите таблицу с 7 столбцами и 100 строками и заполняйте их правильными днями. Вам нужно делать это только один раз каждые 100 лет и принимать меньше часа, и он переносится.

Давайте будем гением компьютера.