2010-09-14 14 views
24

Estoy buscando una clase/biblioteca C# que funcione de manera similar al módulo Perl Date::Manip en lo que respecta a fechas de negocios/vacaciones. Utilizando ese módulo en Perl, puedo pasarle una fecha y averiguar si es un día hábil (es decir, de lunes a viernes) o unas vacaciones. Las vacaciones son muy simples de definir en un archivo de configuración (ver Date::Manip::Holidays). Puede introducir una fecha 'fija' que se aplica a todos los años, como:Manejo de fechas comerciales/festivas

12/25       = Christmas 

o fechas 'dinámicas' por cada año como:

last Monday in May    = Memorial Day 

o 'fijo' data de un año determinado como:

5/22/2010      = Bob's Wedding 

También puede pasar una fecha y volver el día hábil anterior/anterior.

¿Alguien sabe de algo así en el mundo de C#? He encontrado un par de cosas que implementan partes de lo que necesito (http://www.codeproject.com/KB/cs/busdatescalculation.aspx y http://www.codeproject.com/KB/dotnet/HolidayCalculator.aspx) y puedo separarlas y hacer lo que necesito. Pero si alguien más ya lo hizo, ¿por qué hacerlo de nuevo?

Gracias!

de Dave

+1

Fecha :: Manip sabe cuándo boda de Bob es !? – dtb

+0

¡Lo hace si lo defines en el archivo de configuración! :) – DaveKub

Respuesta

-1

no veo nada en la fecha :: Manip que ya no se proporciona como parte de .NET Framework. ¿No funciona el this para el día de la semana?

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

La descripción de la fecha :: Manip lee:

Fecha :: Manip es una serie de módulos diseñados para hacer cualquier manipulación común fecha/hora fácil de hacer. Las operaciones como comparar dos veces, calcular el tiempo de una determinada cantidad de tiempo o analizar los tiempos internacionales se hacen fácilmente.

Todo esto viene con la clase DateTime.

+0

Que yo sepa, no hay nada en el .NET Framework que haga algo con 'feriados'. Necesito saber si una fecha determinada es feriado o no, y las vacaciones deben poder definirse a medida. – DaveKub

+0

Eso es solo una comparación de fecha contra una lista. Use un XmlDocument para leer en las fechas personalizadas, llenar una lista y luego compararla. – Amy

+2

No quiero utilizar una lista de fechas para las vacaciones, deben ser dinámicas (como los ejemplos que di). Estoy buscando algo que sepa en qué día cae el Día del Trabajo en 2012 (o 2013 o 2020, etc.) sin que tenga que poner la fecha explícita completa en una lista en algún lugar. – DaveKub

-1

Date::Manip puede manejar reglas complicadas, como el Viernes Santo. Aquí está la definición de Viernes Santo en el archivo Date::Manipholidays.cnf que utilizo:

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

Internamente, tiene la lógica para determinar cuándo Pascua se basa en las fases de la luna.

+1

Sí, pero la pregunta era sobre encontrar una biblioteca C# que pudiera hacer lo que 'Date :: Manip' hace. – DaveKub

2

La drules project es una biblioteca que puede usar para generar este tipo de reglas.

El último lunes de mayo sería:

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

Aquí es una calculadora horas comerciales que también se ocupa de los feriados utilizados por las instituciones financieras. Comprueba todas las 9 Festividades de Mercado y puede modificar sus Horas de atención para los fines de semana o los fines de semana.

Business Hours Calculator

17

Un poco tarde a la fiesta, pero la figura hacia ayudará a otras personas googling. Encontré una buena respuesta al http://geekswithblogs.net/wpeck/archive/2011/12/27/us-holiday-list-in-c.aspx. Incluso toma en cuenta las vacaciones que caen en un fin de semana.

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's 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; 
     } 
    } 
+2

Tenga en cuenta que, dependiendo de su caso de uso, es posible que deba dar cuenta cuando el Día de Año Nuevo sea un sábado. Por ejemplo, 31/12/2010 sería el día observado para 1/1/2011. –

+0

@FacioRatio Mira el método AdjustForWeekendHoliday en la parte inferior. Toma la fecha de la fiesta, luego resta un día si es un sábado, y agrega un día si es un domingo. – Todes3ngel

+0

Correcto, pero en mi caso, dado que el día observado a veces es en un año diferente, necesitaba dar cuenta de eso. Sin embargo, en cuanto a solo decirte cuáles son las vacaciones observadas para un año determinado, funcionó muy bien para mí, ¡gracias! –

10

Nager.Date soporta más de 70 países (Estados Unidos, Alemania, Francia, RU, Reino Unido, ...) la biblioteca está disponible para .net45 y .netstandard 2.0. La lista de países completa está disponible en la página de github.

Nuget

PM> install-package Nager.Date 

Ejemplo:

obtener todos publicholidays de un año

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

Comprobar si una fecha un día festivo

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

Si te interesa un amplio por país de referencia. Estoy pensando en QuantLib que inicialmente se enfoca en días festivos bancarios o de intercambio. Puede construir la biblioteca en C# si es necesario, aunque eso podría ser pesado para hacerlo.

En cualquier caso, esa es de lejos la mejor referencia que puedo encontrar.

QuantLib: Calendars

+0

por favor brinde una respuesta a la pregunta (con un ejemplo) y no solo un enlace. – loki

+0

Por favor, publique las partes principales del enlace en su respuesta. Si en el futuro ese enlace se rompe, esta respuesta será inútil – acostela