Vali-Calendar
1.0.0
dotnet add package Vali-Calendar --version 1.0.0
NuGet\Install-Package Vali-Calendar -Version 1.0.0
<PackageReference Include="Vali-Calendar" Version="1.0.0" />
<PackageVersion Include="Vali-Calendar" Version="1.0.0" />
<PackageReference Include="Vali-Calendar" />
paket add Vali-Calendar --version 1.0.0
#r "nuget: Vali-Calendar, 1.0.0"
#:package Vali-Calendar@1.0.0
#addin nuget:?package=Vali-Calendar&version=1.0.0
#tool nuget:?package=Vali-Calendar&version=1.0.0
Vali-Calendar
Calendar-aware workday calculations, week metadata, and optional public holiday integration for .NET.
Features
WeekOf(date)returns aCalendarWeekwith week number, ISO year, start and end datesWeeksInMonthandWeekCountInMonthfor calendar grid generationIsWorkday— excludes weekends and, when a holiday provider is configured, also public holidaysWorkdaysBetween,WorkdaysInMonth,WorkdaysInYearfor business-day countingAddWorkdaysto advance a date by N business days, skipping weekends and holidaysNextWorkday/PreviousWorkdayto find the nearest valid business dayHolidaysInMonth/HolidaysInYearpowered by a pluggableIHolidayProviderIsFirstDayOfMonth,IsLastDayOfMonth,DaysInMonth,DaysOfMonth,IsLeapYear,DaysInYear- Configurable week start: Monday (ISO 8601) or Sunday
- Zero dependencies beyond Vali-Time and Vali-Holiday (both optional at runtime)
Installation
dotnet add package Vali-Calendar
Compiled targets: net8.0 · net9.0. Compatible with .NET 6 and .NET 7 via NuGet backward compatibility — no separate build needed.
Quick Start
using Vali_Calendar.Core;
// Without holiday provider — weekends only
var calendar = new ValiCalendar();
DateTime orderDate = new DateTime(2025, 3, 20); // Thursday
DateTime deliveryDate = calendar.AddWorkdays(orderDate, 5);
Console.WriteLine(deliveryDate.ToString("yyyy-MM-dd")); // "2025-03-27"
int workdays = calendar.WorkdaysBetween(
new DateTime(2025, 3, 1),
new DateTime(2025, 3, 31));
Console.WriteLine($"Workdays in March 2025: {workdays}"); // 21
API Reference
Constructor
// Weekends only (no holiday awareness)
var calendar = new ValiCalendar();
var calendarSun = new ValiCalendar(WeekStart.Sunday);
// With a holiday provider (also excludes public holidays from workday logic)
// IHolidayProvider is implemented in Vali-Holiday or by your own class
var calendarWithHolidays = new ValiCalendar(WeekStart.Monday, myHolidayProvider);
Week Methods
WeekOf
Returns a CalendarWeek for any date.
var calendar = new ValiCalendar();
var date = new DateTime(2025, 3, 21); // Friday
CalendarWeek week = calendar.WeekOf(date);
Console.WriteLine(week.WeekNumber); // 12
Console.WriteLine(week.Year); // 2025
Console.WriteLine(week.Start.ToString("yyyy-MM-dd")); // "2025-03-17"
Console.WriteLine(week.End.ToString("yyyy-MM-dd")); // "2025-03-23"
CurrentWeek
CalendarWeek thisWeek = calendar.CurrentWeek();
WeeksInMonth / WeekCountInMonth
Useful for building calendar grid views.
// All calendar weeks that overlap with March 2025
IEnumerable<CalendarWeek> weeks = calendar.WeeksInMonth(2025, 3);
foreach (var w in weeks)
Console.WriteLine($"Week {w.WeekNumber}: {w.Start:yyyy-MM-dd} → {w.End:yyyy-MM-dd}");
int count = calendar.WeekCountInMonth(2025, 3); // 6
Month Methods
var date = new DateTime(2025, 3, 1);
calendar.IsFirstDayOfMonth(date); // true
calendar.IsLastDayOfMonth(date); // false
var lastDay = new DateTime(2025, 3, 31);
calendar.IsLastDayOfMonth(lastDay); // true
int days = calendar.DaysInMonth(new DateTime(2025, 2, 10)); // 28
// Enumerate every day in February 2025
foreach (DateTime d in calendar.DaysOfMonth(2025, 2))
Console.WriteLine(d.ToString("yyyy-MM-dd"));
Workday Methods
IsWorkday
var calendar = new ValiCalendar();
calendar.IsWorkday(new DateTime(2025, 3, 21)); // true (Friday)
calendar.IsWorkday(new DateTime(2025, 3, 22)); // false (Saturday)
calendar.IsWorkday(new DateTime(2025, 3, 23)); // false (Sunday)
With a holiday provider, a public holiday on a weekday also returns false.
WorkdaysBetween
Inclusive count of workdays from from to to.
int count = calendar.WorkdaysBetween(
new DateTime(2025, 3, 1),
new DateTime(2025, 3, 31));
Console.WriteLine(count); // 21
int countYear = calendar.WorkdaysInYear(2025);
Console.WriteLine(countYear); // 261
AddWorkdays
Advance a date by exactly N business days, skipping weekends (and holidays when configured).
// Start on a Friday
DateTime start = new DateTime(2025, 3, 21);
DateTime result = calendar.AddWorkdays(start, 3);
Console.WriteLine(result.ToString("yyyy-MM-dd")); // "2025-03-26" (Wed, skips Sat+Sun)
// Negative: go backward
DateTime back = calendar.AddWorkdays(start, -3);
Console.WriteLine(back.ToString("yyyy-MM-dd")); // "2025-03-18" (Tue)
NextWorkday / PreviousWorkday
If the date is already a workday it is returned unchanged.
// Saturday → next workday is Monday
DateTime sat = new DateTime(2025, 3, 22);
DateTime next = calendar.NextWorkday(sat);
Console.WriteLine(next.ToString("yyyy-MM-dd")); // "2025-03-24"
DateTime friday = new DateTime(2025, 3, 21);
DateTime prev = calendar.PreviousWorkday(friday);
Console.WriteLine(prev.ToString("yyyy-MM-dd")); // "2025-03-21" (already a workday)
Holiday Integration
Holiday methods require an IHolidayProvider to be passed to the constructor. Without it, calling HolidaysInMonth or HolidaysInYear throws InvalidOperationException.
// Assuming MyHolidayProvider implements IHolidayProvider
var provider = new MyHolidayProvider();
var calendarH = new ValiCalendar(WeekStart.Monday, provider);
// Check if a holiday provider is set
Console.WriteLine(calendarH.HasHolidayProvider); // true
// List holidays in April 2025
foreach (HolidayInfo h in calendarH.HolidaysInMonth(2025, 4))
Console.WriteLine($"{h.Date:yyyy-MM-dd} — {h.Name}");
// List all holidays in 2025
foreach (HolidayInfo h in calendarH.HolidaysInYear(2025))
Console.WriteLine($"{h.Date:yyyy-MM-dd} — {h.Name}");
Year Methods
calendar.IsLeapYear(2024); // true
calendar.IsLeapYear(2025); // false
calendar.DaysInYear(2024); // 366
calendar.DaysInYear(2025); // 365
Practical Example: Delivery Date Without vs With Holidays
using Vali_Calendar.Core;
// --- Without holiday provider ---
var calendar = new ValiCalendar();
DateTime orderFriday = new DateTime(2025, 4, 17); // Thursday before Easter
DateTime deliveryBase = calendar.AddWorkdays(orderFriday, 5);
Console.WriteLine(deliveryBase.ToString("yyyy-MM-dd")); // "2025-04-24"
// --- With holiday provider (Easter Friday = 2025-04-18 is a holiday) ---
// var provider = new MyHolidayProvider(); // returns 2025-04-18 as a holiday
// var calendarH = new ValiCalendar(WeekStart.Monday, provider);
// DateTime deliveryWithHoliday = calendarH.AddWorkdays(orderFriday, 5);
// Console.WriteLine(deliveryWithHoliday.ToString("yyyy-MM-dd")); // "2025-04-25" (one extra day)
// --- Count workdays in the current month ---
int workdaysThisMonth = calendar.WorkdaysInMonth(2025, 3);
Console.WriteLine($"March 2025 has {workdaysThisMonth} workdays."); // 21
// --- Calendar week view for a month ---
foreach (CalendarWeek week in calendar.WeeksInMonth(2025, 3))
{
Console.WriteLine(
$"W{week.WeekNumber:D2} ({week.Year}): " +
$"{week.Start:MMM dd} – {week.End:MMM dd}");
}
Dependency Injection
using Vali_Calendar.Core;
// Without holidays
services.AddSingleton<IValiCalendar, ValiCalendar>();
// With a holiday provider registered separately
services.AddSingleton<IHolidayProvider, MyHolidayProvider>();
services.AddSingleton<IValiCalendar>(sp =>
new ValiCalendar(
WeekStart.Monday,
sp.GetRequiredService<IHolidayProvider>()));
License
MIT
Donations
If this package is useful to you, consider supporting its development:
- Latin America — MercadoPago
- International — PayPal
| Product | Versions 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. |
-
net8.0
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 9.0.0)
- Vali-Holiday (>= 1.0.0)
- Vali-Time (>= 1.0.1)
-
net9.0
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 9.0.0)
- Vali-Holiday (>= 1.0.0)
- Vali-Time (>= 1.0.1)
NuGet packages (1)
Showing the top 1 NuGet packages that depend on Vali-Calendar:
| Package | Downloads |
|---|---|
|
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 | 144 | 3/26/2026 |
Vali-Calendar v1.0.0 — initial release: ValiCalendar with WorkdaysBetween, AddWorkdays, WorkdaysInMonth, WorkdaysInYear, NextWorkday, PreviousWorkday, WeekOf, WeeksInMonth, CalendarWeek struct, and month/year helpers.