Подтвердить что ты не робот

Обработка деловых/праздничных дней

Я ищу класс/библиотеку С#, которая работает аналогично модулю Perl Date::Manip, насколько это касается дат деловых/праздничных дней. Используя этот модуль в Perl, я могу передать ему дату и узнать, будет ли это рабочий день (т.е. понедельник-пятница) или праздник. Праздники очень просто определить в файле конфигурации (см. Date::Manip::Holidays). Вы можете ввести "фиксированную" дату, которая применяется к каждому году, например:

12/25                           = Christmas

или "динамические" даты для каждого года, например:

last Monday in May              = Memorial Day

или "фиксированные" даты для данного года, например:

5/22/2010                       = Bob Wedding

Вы также можете указать дату и вернуться на следующий/предыдущий рабочий день.

Кто-нибудь знает что-нибудь подобное в мире С#? Я нашел несколько вещей, которые реализуют части того, что мне нужно (http://www.codeproject.com/KB/cs/busdatescalculation.aspx и http://www.codeproject.com/KB/dotnet/HolidayCalculator.aspx), и я могу выделить их и сделать то, что мне нужно. Но если кто-то уже сделал это, зачем делать это снова?

4b9b3361

Ответ 1

Я не мог найти ничего, что делало именно то, что я хотел, поэтому я использовал код http://www.codeproject.com/KB/dotnet/HolidayCalculator.aspx и модифицировал его в соответствии с моими потребностями, Он сделал большую часть того, что мне было нужно, поэтому он не сильно задумывался.

Ответ 2

Nager.Date поддерживает более 100 стран (США, DE, FR, RU, UK,...), библиотека доступна для .net45 и .netstandard 2.0. Полный список стран доступен на странице GitHub.

NuGet

PM> install-package Nager.Date

Пример:

Получите все публичные праздники года

var publicHolidays = DateSystem.GetPublicHoliday(2018, CountryCode.DE);

Проверьте, является ли дата выходным днем

var date = new DateTime(2018, 01, 01);
if (DateSystem.IsPublicHoliday(date, CountryCode.DE))
{
    //Yes - New Year Day
}

Ответ 3

Немного поздно на вечеринку, но фигура это поможет другим людям погулять. Нашел хороший ответ на http://geekswithblogs.net/wpeck/archive/2011/12/27/us-holiday-list-in-c.aspx. Это даже учитывает праздники, которые выпадают на выходные.

private static HashSet<DateTime> GetHolidays(int year) 
    { 
        HashSet<DateTime> holidays = new HashSet<DateTime>();

        // New Years
        DateTime newYearsDate = AdjustForWeekendHoliday(new DateTime(year, 1, 1)); 
        holidays.Add(newYearsDate); 

        // Memorial Day -- last monday in May 
        DateTime memorialDay = new DateTime(year, 5, 31); 
        DayOfWeek dayOfWeek = memorialDay.DayOfWeek; 
        while (dayOfWeek != DayOfWeek.Monday) 
        { 
            memorialDay = memorialDay.AddDays(-1); 
            dayOfWeek = memorialDay.DayOfWeek; 
        } 
        holidays.Add(memorialDay); 

        // Independence Day
        DateTime independenceDay = AdjustForWeekendHoliday(new DateTime(year, 7, 4)); 
        holidays.Add(independenceDay); 

        // Labor Day -- 1st Monday in September 
        DateTime laborDay = new DateTime(year, 9, 1); 
        dayOfWeek = laborDay.DayOfWeek; 
        while(dayOfWeek != DayOfWeek.Monday) 
        { 
            laborDay = laborDay.AddDays(1); 
            dayOfWeek = laborDay.DayOfWeek; 
        } 
        holidays.Add(laborDay);

        // Thanksgiving Day -- 4th Thursday in November 
        var thanksgiving = (from day in Enumerable.Range(1, 30) 
                       where new DateTime(year, 11, day).DayOfWeek == DayOfWeek.Thursday 
                       select day).ElementAt(3); 
        DateTime thanksgivingDay = new DateTime(year, 11, thanksgiving); 
        holidays.Add(thanksgivingDay);

        // Christmas Day 
        DateTime christmasDay = AdjustForWeekendHoliday(new DateTime(year, 12, 25)); 
        holidays.Add(christmasDay); 

        // Next year new years check
        DateTime nextYearNewYearsDate = AdjustForWeekendHoliday(new DateTime(year + 1, 1, 1));
        if (nextYearNewYearsDate.Year == year)
        holidays.Add(nextYearNewYearsDate);

        return holidays; 
    }

    public static DateTime AdjustForWeekendHoliday(DateTime holiday) 
    { 
        if (holiday.DayOfWeek == DayOfWeek.Saturday) 
        { 
            return holiday.AddDays(-1); 
        } 
        else if (holiday.DayOfWeek == DayOfWeek.Sunday) 
        { 
            return holiday.AddDays(1); 
        } 
        else 
        { 
            return holiday; 
        } 
    }

Ответ 4

Проект drules - это библиотека, которую вы можете использовать для создания таких правил.

Последний понедельник мая:

roll(*/5/last, -1, mon)

Ответ 5

Если вас интересует обширная по стране ссылка. Я думаю о QuantLib, который первоначально фокусируется на банковских или обменных отпусках. Вы можете построить библиотеку в С#, если это необходимо, хотя это может быть тяжело для этого.

В любом случае я могу найти наилучшую ссылку.

QuantLib: Календари

Ответ 6

Я ничего не вижу в Date:: Manip, который еще не предоставлен как часть .NET Framework. Не этот работает в течение дня недели?

DateTime dt = DateTime.Now;
Console.WriteLine(dt.DayOfWeek);

Описание Date:: Manip читает:

Date:: Manip - это серия модулей, предназначенная для облегчения повседневной манипуляции с датой и временем. Операции, такие как сравнение двух раз, вычисление времени определенного количества времени от другого или разбор международного времени, легко выполняются.

Все это поставляется с классом DateTime.

Ответ 7

Date::Manip может обрабатывать сложные правила, такие как хорошая пятница. Здесь определение хорошей пятницы в файле Date::Manip holidays.cnf, которое я использую:

1*0:0:0:0:0:0*EASTER,PD5    = Good Friday

Внутри, у нее есть логика, чтобы определить, когда Пасха основана на фазах Луны.

Ответ 8

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

Калькулятор деловых часов