Vali-Holiday 1.0.0

dotnet add package Vali-Holiday --version 1.0.0
                    
NuGet\Install-Package Vali-Holiday -Version 1.0.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Vali-Holiday" Version="1.0.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Vali-Holiday" Version="1.0.0" />
                    
Directory.Packages.props
<PackageReference Include="Vali-Holiday" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Vali-Holiday --version 1.0.0
                    
#r "nuget: Vali-Holiday, 1.0.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Vali-Holiday@1.0.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Vali-Holiday&version=1.0.0
                    
Install as a Cake Addin
#tool nuget:?package=Vali-Holiday&version=1.0.0
                    
Install as a Cake Tool

Vali-Holiday

Official public holiday data for 35 countries across Latin America, Europe, and beyond — with multilingual names, Easter calculations, and an extensible provider model.

Features

  • 35 countries built-in across Latin America, Europe, Canada, and Australia
  • HolidayProviderFactory — create pre-configured instances with CreateAll(), CreateLatinAmerica(), CreateEurope(), or CreateOther()
  • IsHoliday — check whether a date is a national public holiday (regional holidays excluded)
  • GetHolidays — all holidays for a year in one or multiple countries
  • GetNextHolidayWithYear / GetPreviousHolidayWithYear — navigate holidays forward and backward, returning both the holiday and the year it falls in
  • GetNextHoliday / GetPreviousHoliday (deprecated) — use GetNextHolidayWithYear instead
  • IsLongWeekend — detect holidays on Monday or Friday that extend the weekend
  • HolidaysThisMonth — filter holidays by month
  • Multilingual namesGetName(holiday, "en") supports "es", "en", "pt", "fr", "de"
  • Movable holidays — Easter-based dates (Good Friday, Corpus Christi, etc.) computed per year
  • IHolidayProvider — implement your own provider for unsupported countries or regional calendars
  • Registered as a singleton via AddValiHoliday()
  • Compiled targets: net8.0 · net9.0 — compatible with .NET 6+ via NuGet backward compatibility

Installation

dotnet add package Vali-Holiday

Compatible with .NET 6, 7, 8, and 9. For new projects, .NET 8 (LTS) or .NET 9 is recommended.

Quick Start

using Vali_Holiday.Core;

// Load all built-in providers (35 countries)
var holidays = HolidayProviderFactory.CreateAll();

// Is today a public holiday in Peru?
bool isHoliday = holidays.IsHoliday(DateTime.Today, "PE");

// What is the next holiday in Chile?
var next = holidays.GetNextHolidayWithYear(DateTime.Today, "CL");
if (next is not null)
    Console.WriteLine($"{next.Value.Holiday.Name} — {next.Value.Year}");

Supported Countries

Latin America (15 countries)

Country Code Country Code
Peru PE Uruguay UY
Chile CL Paraguay PY
Argentina AR Venezuela VE
Colombia CO Panama PA
Mexico MX Costa Rica CR
Brazil BR Dominican Republic DO
Ecuador EC Cuba CU
Bolivia BO

Europe (17 countries)

Country Code Country Code
Spain ES Switzerland CH
United States US Austria AT
United Kingdom GB Poland PL
Germany DE Sweden SE
France FR Norway NO
Italy IT Denmark DK
Portugal PT Finland FI
Netherlands NL Ireland IE
Belgium BE

Other (3 countries)

Country Code
Canada CA
Australia AU

API Reference

HolidayProviderFactory

// All 35 countries
ValiHoliday all    = HolidayProviderFactory.CreateAll();

// Only Latin American countries (15)
ValiHoliday latam  = HolidayProviderFactory.CreateLatinAmerica();

// Only European + US countries (17)
ValiHoliday europe = HolidayProviderFactory.CreateEurope();

// Canada and Australia
ValiHoliday other  = HolidayProviderFactory.CreateOther();

IsHoliday

bool IsHoliday(DateTime date, string countryCode);
var holidays = HolidayProviderFactory.CreateAll();

bool peruIndependence = holidays.IsHoliday(new DateTime(2025, 7, 28), "PE"); // true
bool randomDay        = holidays.IsHoliday(new DateTime(2025, 3, 5),  "CL"); // false

GetHolidays

// All holidays in a country for a year
IEnumerable<HolidayInfo> GetHolidays(int year, string countryCode);

// Holidays across multiple countries
IEnumerable<HolidayInfo> GetHolidays(int year, params string[] countryCodes);
var peruHolidays2025 = holidays.GetHolidays(2025, "PE");
foreach (var h in peruHolidays2025)
    Console.WriteLine($"{h.Month:D2}/{h.Day:D2} — {h.Name}");

// Multi-country query
var andean = holidays.GetHolidays(2025, "PE", "CL", "BO");

GetNextHolidayWithYear / GetPreviousHolidayWithYear

Returns the next or previous holiday together with the calendar year it falls in. This is essential for movable holidays (Easter-based dates) whose month/day changes every year. Searches up to one year ahead or back. Returns null if no holiday is found in that window.

(HolidayInfo Holiday, int Year)? GetNextHolidayWithYear(DateTime date, string countryCode);
(HolidayInfo Holiday, int Year)? GetPreviousHolidayWithYear(DateTime date, string countryCode);
var next = holidays.GetNextHolidayWithYear(DateTime.Today, "AR");
if (next is not null)
    Console.WriteLine($"Next holiday: {next.Value.Holiday.Name} in {next.Value.Year}");

var prev = holidays.GetPreviousHolidayWithYear(DateTime.Today, "MX");

GetNextHoliday / GetPreviousHoliday (deprecated)

Obsolete. Use GetNextHolidayWithYear / GetPreviousHolidayWithYear instead. These overloads return only the HolidayInfo without the resolved year, which makes movable holidays ambiguous. They will be removed in a future version.

HolidayInfo? GetNextHoliday(DateTime date, string countryCode);
HolidayInfo? GetPreviousHoliday(DateTime date, string countryCode);

IsLongWeekend

Returns true when the date is a public holiday that falls on a Monday or Friday, creating a 3-day weekend.

bool IsLongWeekend(DateTime date, string countryCode);
// Check every day in 2025 for long weekends in Chile
for (var d = new DateTime(2025, 1, 1); d.Year == 2025; d = d.AddDays(1))
{
    if (holidays.IsLongWeekend(d, "CL"))
        Console.WriteLine($"Long weekend: {d:yyyy-MM-dd} ({d.DayOfWeek})");
}

HolidaysThisMonth

IEnumerable<HolidayInfo> HolidaysThisMonth(int year, int month, string countryCode);
var julyHolidays = holidays.HolidaysThisMonth(2025, 7, "PE");
foreach (var h in julyHolidays)
    Console.WriteLine($"{h.Day:D2} — {h.Name}"); // 28 — Fiestas Patrias, 29 — ...

Multilingual Names

HolidayInfo carries a Names dictionary keyed by BCP 47 language tags. Use IHolidayProvider.GetName() to get the name in a specific language with automatic fallback.

var provider = holidays.For("PE");
var holiyday = holidays.GetNextHoliday(DateTime.Today, "PE")!;

string spanish  = provider.GetName(holiyday, "es"); // "Año Nuevo"
string english  = provider.GetName(holiyday, "en"); // "New Year's Day"
string french   = provider.GetName(holiyday, "fr"); // "Jour de l'An"
string german   = provider.GetName(holiyday, "de"); // "Neujahr"

HolidayInfo Model

Property Type Description
Id string Unique identifier (e.g., "pe_independence")
Month int Month (1–12)
Day int Day of month (1–31)
CountryCode string ISO 3166-1 alpha-2
Name string Name in the country's primary language
Names IReadOnlyDictionary<string, string> Multilingual names ("es", "en", "pt", "fr", "de")
Type HolidayType National, Religious, Civic, etc.
IsMovable bool true for Easter-based or floating holidays
RegionCode string? ISO 3166-2 region code, or null for national holidays
Description string? Optional cultural or historical context
// Convert to DateTime for a specific year
DateTime date = holiday.ToDateTime(2025);

// Default string representation
Console.WriteLine(holiday); // "[PE] 07/28 - Fiestas Patrias"

Custom IHolidayProvider

Implement IHolidayProvider to add support for a country or custom calendar not included in the built-in set.

using Vali_Holiday.Core;
using Vali_Holiday.Models;

public class JapanHolidayProvider : IHolidayProvider
{
    public string CountryCode    => "JP";
    public string CountryName    => "Japan";
    public string PrimaryLanguage => "ja";

    public IEnumerable<HolidayInfo> GetHolidays(int year)
    {
        var names = new Dictionary<string, string>
        {
            ["ja"] = "元日",
            ["en"] = "New Year's Day"
        };

        yield return new HolidayInfo(
            id:          "jp_new_year",
            month:       1,
            day:         1,
            countryCode: "JP",
            name:        "元日",
            names:       names.AsReadOnly(),
            type:        HolidayType.National);
        // ... additional holidays
    }

    public bool IsHoliday(DateTime date) =>
        GetHolidays(date.Year).Any(h => h.Month == date.Month && h.Day == date.Day);

    public bool IsHoliday(DateOnly date) =>
        IsHoliday(date.ToDateTime(TimeOnly.MinValue));

    public HolidayInfo? GetHoliday(DateTime date) =>
        GetHolidays(date.Year).FirstOrDefault(h => h.Month == date.Month && h.Day == date.Day);

    public IEnumerable<HolidayInfo> GetHolidaysInRange(DateTime from, DateTime to)
    {
        for (int y = from.Year; y <= to.Year; y++)
            foreach (var h in GetHolidays(y))
            {
                var d = new DateTime(y, h.Month, h.Day);
                if (d >= from.Date && d <= to.Date) yield return h;
            }
    }

    public string GetName(HolidayInfo holiday, string languageCode) =>
        holiday.Names.TryGetValue(languageCode, out var name) ? name : holiday.Name;
}

// Register the custom provider
var holidays = HolidayProviderFactory.CreateAll();
holidays.Register(new JapanHolidayProvider());

bool isNewYear = holidays.IsHoliday(new DateTime(2025, 1, 1), "JP"); // true

Practical Examples

Calculate business days in Peru excluding public holidays
var holidays = HolidayProviderFactory.CreateLatinAmerica();

var start = new DateTime(2025, 7, 1);
var end   = new DateTime(2025, 7, 31);

int businessDays = 0;
for (var d = start; d <= end; d = d.AddDays(1))
{
    if (d.DayOfWeek == DayOfWeek.Saturday) continue;
    if (d.DayOfWeek == DayOfWeek.Sunday)   continue;
    if (holidays.IsHoliday(d, "PE"))        continue;
    businessDays++;
}

Console.WriteLine($"Business days in July 2025 (PE): {businessDays}");
// July has Fiestas Patrias on 28 & 29, so result will be less than 23
Detect long weekends in Chile for 2025
var holidays = HolidayProviderFactory.CreateLatinAmerica();

Console.WriteLine("Long weekends in Chile 2025:");
for (var d = new DateTime(2025, 1, 1); d.Year == 2025; d = d.AddDays(1))
{
    if (holidays.IsLongWeekend(d, "CL"))
    {
        var info = holidays.GetNextHolidayWithYear(d, "CL");
        Console.WriteLine($"  {d:yyyy-MM-dd} ({d.DayOfWeek}) — {info?.Holiday.Name}");
    }
}

Dependency Injection

// Program.cs — ASP.NET Core
using Vali_Holiday.Extensions;

// Registers ValiHoliday as a singleton pre-loaded with ALL built-in country providers
builder.Services.AddValiHoliday();

Inject ValiHoliday directly:

public class PayrollService(ValiHoliday holidays)
{
    public bool IsWorkday(DateTime date, string countryCode)
    {
        if (date.DayOfWeek is DayOfWeek.Saturday or DayOfWeek.Sunday) return false;
        return !holidays.IsHoliday(date, countryCode);
    }
}

License

Licensed under the MIT License. Copyright © 2025 Felipe Rafael Montenegro Morriberon. All rights reserved.

Donations

If this package is useful to you, consider supporting its development:


Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 is compatible.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (2)

Showing the top 2 NuGet packages that depend on Vali-Holiday:

Package Downloads
Vali-Calendar

Vali-Calendar is a .NET library for calendar-based operations. Provides workday calculations, ISO week numbers, CalendarWeek struct, month/year utilities, and business-day arithmetic without requiring external holiday providers.

Vali-Tempo

Vali-Tempo is the all-in-one meta-package for the Vali-Tempo ecosystem. Installing it gives you every module — Vali-Time, Vali-Range, Vali-Calendar, Vali-CountDown, Vali-Age, Vali-Holiday, Vali-TimeZone, Vali-Schedule, and Vali-Duration — with a single NuGet reference and a single DI registration call.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.0.0 169 3/26/2026

Vali-Holiday v1.0.0 — initial release with providers for 35+ countries, multilingual names, Easter calculation (Gaussian algorithm), movable holidays, O(1) HashSet cache, and HolidayProviderFactory.