Vali-Calendar
IValiCalendar es un motor de calendario con conciencia de días laborables que admite proveedores de feriados intercambiables. Puede calcular días laborables entre fechas, agregar días hábiles, detectar límites de mes/semana y enumerar los días de un mes.
Instalación
dotnet add package Vali-Calendar
Registro
builder.Services.AddValiCalendar();
// o mediante el meta-paquete:
builder.Services.AddValiTempo();
Struct CalendarWeek
CalendarWeek representa una semana calendario ISO 8601:
| Propiedad | Tipo | Descripción |
|---|---|---|
Year | int | Año al que pertenece la semana |
WeekNumber | int | Número de semana ISO (1–53) |
Start | DateTime | Lunes de la semana |
End | DateTime | Domingo de la semana |
Days | IEnumerable<DateTime> | Los 7 días de la semana |
API de IValiCalendar
WeekOf
Obtiene el CalendarWeek que contiene una fecha dada:
CalendarWeek week = calendar.WeekOf(new DateTime(2025, 3, 15));
Console.WriteLine(week.WeekNumber); // → número de semana ISO
Console.WriteLine(week.Start); // → lunes de esa semana
Console.WriteLine(week.End); // → domingo de esa semana
Firma: CalendarWeek WeekOf(DateTime date)
CurrentWeek
Obtiene el CalendarWeek para la fecha actual:
CalendarWeek thisWeek = calendar.CurrentWeek();
Firma: CalendarWeek CurrentWeek()
WeeksInMonth
Obtiene todas las semanas calendario que se superponen con el mes de la fecha dada:
IEnumerable<CalendarWeek> weeks = calendar.WeeksInMonth(new DateTime(2025, 3, 1));
// → Todas las semanas que se superponen con marzo de 2025
Firma: IEnumerable<CalendarWeek> WeeksInMonth(DateTime date)
WeekCountInMonth
Devuelve el número de semanas calendario (parciales o completas) en el mes de la fecha dada:
int count = calendar.WeekCountInMonth(new DateTime(2025, 3, 1));
// → 5 (marzo de 2025 abarca 5 semanas)
Firma: int WeekCountInMonth(DateTime date)
IsFirstDayOfMonth
Devuelve true si la fecha es el primer día de su mes calendario:
bool first = calendar.IsFirstDayOfMonth(new DateTime(2025, 5, 1));
// → true
Firma: bool IsFirstDayOfMonth(DateTime date)
IsLastDayOfMonth
Devuelve true si la fecha es el último día de su mes calendario:
bool last = calendar.IsLastDayOfMonth(new DateTime(2025, 1, 31));
// → true
Firma: bool IsLastDayOfMonth(DateTime date)
DaysInMonth
Devuelve el número de días en el mes de la fecha dada:
int days = calendar.DaysInMonth(new DateTime(2024, 2, 10));
// → 29 (año bisiesto)
Firma: int DaysInMonth(DateTime date)
DaysOfMonth
Enumera todos los días calendario del mes de la fecha dada:
IEnumerable<DateTime> days = calendar.DaysOfMonth(new DateTime(2025, 3, 1));
foreach (var day in days)
Console.WriteLine(day.ToString("dd ddd"));
Firma: IEnumerable<DateTime> DaysOfMonth(DateTime date)
IsWorkday
Devuelve true si la fecha es un día laborable (lunes a viernes y no es un feriado registrado):
bool isWork = calendar.IsWorkday(new DateTime(2025, 12, 25));
// → depende de los feriados registrados
Opcionalmente pasa un código de país para verificar con los feriados de ese país:
bool isWork = calendar.IsWorkday(new DateTime(2025, 12, 25), "PE");
Firma: bool IsWorkday(DateTime date, string? country = null)
WorkdaysBetween
Cuenta el número de días laborables entre dos fechas (sin incluir la fecha de fin):
int workdays = calendar.WorkdaysBetween(
new DateTime(2025, 3, 3), // Lunes
new DateTime(2025, 3, 14), // Viernes
"US");
// → 10 (dos semanas de lun–vie)
Firma: int WorkdaysBetween(DateTime from, DateTime to, string? country = null)
AddWorkdays
Añade un número de días hábiles a una fecha, omitiendo fines de semana y feriados:
DateTime result = calendar.AddWorkdays(new DateTime(2025, 3, 28), 5, "PE");
// → Avanza 5 días laborables, omitiendo fines de semana y feriados peruanos
Firma: DateTime AddWorkdays(DateTime date, int count, string? country = null)
WorkdaysInMonth
Devuelve la cantidad de días laborables en el mes de la fecha dada:
int count = calendar.WorkdaysInMonth(new DateTime(2025, 3, 1), "US");
// → ~21 (marzo de 2025 tiene 21 días laborables en EE. UU.)
Firma: int WorkdaysInMonth(DateTime date, string? country = null)
WorkdaysInYear
Devuelve la cantidad de días laborables en el año de la fecha dada:
int count = calendar.WorkdaysInYear(new DateTime(2025, 1, 1), "US");
// → ~261
Firma: int WorkdaysInYear(DateTime date, string? country = null)
NextWorkday
Devuelve el siguiente día laborable después de la fecha dada:
DateTime next = calendar.NextWorkday(new DateTime(2025, 3, 28)); // Viernes
// → 2025-03-31 (Lunes)
Firma: DateTime NextWorkday(DateTime date, string? country = null)
PreviousWorkday
Devuelve el día laborable inmediatamente anterior a la fecha dada:
DateTime prev = calendar.PreviousWorkday(new DateTime(2025, 3, 31)); // Lunes
// → 2025-03-28 (Viernes)
Firma: DateTime PreviousWorkday(DateTime date, string? country = null)
HasHolidayProvider
Devuelve true si hay un proveedor de feriados registrado para el código de país dado:
bool has = calendar.HasHolidayProvider("PE");
Firma: bool HasHolidayProvider(string country)
HolidaysInMonth
Devuelve todos los feriados registrados en el mes de la fecha dada para un país:
IEnumerable<HolidayInfo> holidays = calendar.HolidaysInMonth(new DateTime(2025, 12, 1), "PE");
Firma: IEnumerable<HolidayInfo> HolidaysInMonth(DateTime date, string country)
HolidaysInYear
Devuelve todos los feriados registrados en el año de la fecha dada para un país:
IEnumerable<HolidayInfo> holidays = calendar.HolidaysInYear(new DateTime(2025, 1, 1), "US");
Firma: IEnumerable<HolidayInfo> HolidaysInYear(DateTime date, string country)
IsLeapYear
Devuelve true si el año de la fecha dada es un año bisiesto:
bool leap = calendar.IsLeapYear(new DateTime(2024, 1, 1));
// → true
Firma: bool IsLeapYear(DateTime date)
DaysInYear
Devuelve el número de días en el año de la fecha dada (365 o 366):
int days = calendar.DaysInYear(new DateTime(2024, 6, 1));
// → 366
Firma: int DaysInYear(DateTime date)
Ejemplo completo
public class HRCalendar(IValiCalendar calendar, IValiHoliday holiday)
{
public void Setup()
{
// Registrar proveedores de feriados
foreach (var p in HolidayProviderFactory.CreateLatinAmerica())
holiday.Register(p);
}
public void PrintMonthSummary(DateTime date, string country)
{
Console.WriteLine($"Days in month: {calendar.DaysInMonth(date)}");
Console.WriteLine($"Workdays in month: {calendar.WorkdaysInMonth(date, country)}");
Console.WriteLine($"Weeks in month: {calendar.WeekCountInMonth(date)}");
Console.WriteLine("Holidays this month:");
foreach (var h in calendar.HolidaysInMonth(date, country))
Console.WriteLine($" {h.Date:MMM dd} — {h.Name}");
}
public DateTime ComputePaymentDate(DateTime issueDate, string country)
{
// Pago vence 5 días hábiles después de la fecha de factura
return calendar.AddWorkdays(issueDate, 5, country);
}
}