Ir al contenido principal

Proveedores de feriados

Vali-Holiday usa un patrón de proveedor. Cada IHolidayProvider entrega datos de feriados para un país. HolidayProviderFactory ofrece agrupaciones predefinidas para un registro masivo conveniente.

Interfaz IHolidayProvider

public interface IHolidayProvider
{
/// <summary>Código de país ISO 3166-1 alpha-2 (ej. "PE", "US", "ES").</summary>
string CountryCode { get; }

/// <summary>Devuelve todos los feriados públicos del año dado.</summary>
IEnumerable<HolidayInfo> GetHolidays(int year);
}

Implementa esta interfaz para agregar países personalizados o calendarios de feriados específicos de empresa.

HolidayProviderFactory

HolidayProviderFactory es una clase estática que proporciona colecciones predefinidas de proveedores.

CreateAll

Devuelve proveedores para los 35 países admitidos:

foreach (var provider in HolidayProviderFactory.CreateAll())
holiday.Register(provider);

Firma: static IEnumerable<IHolidayProvider> CreateAll()

CreateLatinAmerica

Devuelve proveedores para 15 países latinoamericanos:

foreach (var provider in HolidayProviderFactory.CreateLatinAmerica())
holiday.Register(provider);

Países: Argentina (AR), Bolivia (BO), Brasil (BR), Chile (CL), Colombia (CO), Costa Rica (CR), Cuba (CU), República Dominicana (DO), Ecuador (EC), El Salvador (SV), Guatemala (GT), Honduras (HN), México (MX), Panamá (PA), Paraguay (PY), Perú (PE), Uruguay (UY), Venezuela (VE)

Firma: static IEnumerable<IHolidayProvider> CreateLatinAmerica()

CreateEurope

Devuelve proveedores para 17 países europeos más EE. UU. y Canadá:

foreach (var provider in HolidayProviderFactory.CreateEurope())
holiday.Register(provider);

Países: Austria (AT), Bélgica (BE), Suiza (CH), República Checa (CZ), Alemania (DE), Dinamarca (DK), España (ES), Finlandia (FI), Francia (FR), Reino Unido (GB), Grecia (GR), Hungría (HU), Irlanda (IE), Italia (IT), Países Bajos (NL), Noruega (NO), Polonia (PL), Portugal (PT), Rumanía (RO), Suecia (SE), Canadá (CA), Estados Unidos (US)

Firma: static IEnumerable<IHolidayProvider> CreateEurope()

CreateOther

Devuelve proveedores para los demás países admitidos:

foreach (var provider in HolidayProviderFactory.CreateOther())
holiday.Register(provider);

Países: Australia (AU), Japón (JP), Corea del Sur (KR), Nueva Zelanda (NZ), Filipinas (PH), Rusia (RU), Sudáfrica (ZA)

Firma: static IEnumerable<IHolidayProvider> CreateOther()

Los 35 países admitidos

CódigoPaísRegión
ARArgentinaAmérica Latina
ATAustriaEuropa
AUAustraliaOtros
BEBélgicaEuropa
BOBoliviaAmérica Latina
BRBrasilAmérica Latina
CACanadáNorteamérica
CHSuizaEuropa
CLChileAmérica Latina
COColombiaAmérica Latina
CRCosta RicaAmérica Latina
CUCubaAmérica Latina
CZRepública ChecaEuropa
DEAlemaniaEuropa
DKDinamarcaEuropa
DORepública DominicanaAmérica Latina
ECEcuadorAmérica Latina
ESEspañaEuropa
FIFinlandiaEuropa
FRFranciaEuropa
GBReino UnidoEuropa
GRGreciaEuropa
GTGuatemalaAmérica Latina
HNHondurasAmérica Latina
HUHungríaEuropa
IEIrlandaEuropa
ITItaliaEuropa
JPJapónOtros
KRCorea del SurOtros
MXMéxicoAmérica Latina
NLPaíses BajosEuropa
NONoruegaEuropa
NZNueva ZelandaOtros
PAPanamáAmérica Latina
PEPerúAmérica Latina
PHFilipinasOtros
PLPoloniaEuropa
PTPortugalEuropa
PYParaguayAmérica Latina
RORumaníaEuropa
RURusiaOtros
SESueciaEuropa
SVEl SalvadorAmérica Latina
USEstados UnidosNorteamérica
UYUruguayAmérica Latina
VEVenezuelaAmérica Latina
ZASudáfricaOtros

EasterCalculator

EasterCalculator es un helper estático usado por todos los proveedores que tienen feriados dependientes de la Pascua. Calcula el Domingo de Pascua usando el algoritmo Gregoriano Anónimo:

DateTime easter = EasterCalculator.GetEaster(2025);
// → 2025-04-20

DateTime goodFriday = easter.AddDays(-2);
DateTime holyThurs = easter.AddDays(-3);
DateTime easterMonday = easter.AddDays(1);

Firma: static DateTime GetEaster(int year)

El algoritmo maneja correctamente todos los años desde 1583 en adelante (inicio del calendario gregoriano). Pasar un año anterior a 1583 lanza ArgumentOutOfRangeException (calendario pre-gregoriano). No se requieren dependencias externas.

Países que usan feriados basados en la Pascua

Todos los proveedores latinoamericanos, y la mayoría de los europeos, usan EasterCalculator para feriados móviles incluyendo:

  • Carnaval (Martes Gordo, 47 días antes de la Pascua)
  • Domingo de Ramos (7 días antes de la Pascua)
  • Jueves Santo (3 días antes de la Pascua)
  • Viernes Santo (2 días antes de la Pascua)
  • Sábado Santo (1 día antes de la Pascua)
  • Domingo de Pascua
  • Lunes de Pascua (1 día después de la Pascua)
  • Jueves de la Ascensión (39 días después de la Pascua)
  • Pentecostés / Domingo de Pentecostés (49 días después de la Pascua)
  • Corpus Christi (60 días después de la Pascua)

Comportamiento específico por país

Argentina (AR)

El Domingo de Pascua está tipificado como HolidayType.Observance en el proveedor de Argentina. Los feriados de Observance se excluyen de las verificaciones nacionales de IsHoliday(), por lo que IsHoliday("AR", easterDate) devuelve false para el Domingo de Pascua.

Chile (CL)

El Día de los Pueblos Indígenas es un feriado móvil determinado por el ciclo astronómico del solsticio. Cae el 20 de junio en años bisiestos cercanos al ciclo del solsticio, y el 21 de junio en los demás.

Honduras (HN)

El proveedor de Honduras incluye:

  • 17 de sep — Día del Maestro (feriado cívico fijo)
  • Domingo de Pascua (móvil, basado en la Pascua)

Implementar un proveedor personalizado

public class CompanyHolidayProvider : IHolidayProvider
{
public string CountryCode => "INTERNAL";

public IEnumerable<HolidayInfo> GetHolidays(int year)
{
yield return new HolidayInfo
{
Name = "Company Foundation Day",
LocalName = "Día de Fundación",
Date = new DateTime(year, 6, 15),
Country = CountryCode,
Type = HolidayType.Optional,
IsFixed = true,
};

// Feriado dinámico: primer lunes de marzo
var firstMonday = Enumerable
.Range(1, 7)
.Select(d => new DateTime(year, 3, d))
.First(d => d.DayOfWeek == DayOfWeek.Monday);

yield return new HolidayInfo
{
Name = "Team Day",
Date = firstMonday,
Country = CountryCode,
Type = HolidayType.Optional,
IsFixed = false,
};
}
}

// Registrar:
holiday.Register(new CompanyHolidayProvider());