Skip to content

Business Days

Calculate business days with weekend and holiday awareness.

using Pragmatic.Temporal;
var calculator = new TemporalCalculator();
var today = LocalDate.Today;
// Add 5 business days (skips weekends)
var delivery = calculator.AddBusinessDays(today, 5);
// Count business days between dates
var workDays = calculator.CountBusinessDays(startDate, endDate);
var calculator = new TemporalCalculator(); // Uses NoHolidaysProvider

Define holidays manually:

var holidays = new StaticHolidayProvider(new[]
{
new Holiday(new LocalDate(2024, 1, 1), "New Year's Day"),
new Holiday(new LocalDate(2024, 12, 25), "Christmas"),
new Holiday(new LocalDate(2024, 12, 26), "Boxing Day")
});
var calculator = new TemporalCalculator(holidays);

Implement IHolidayProvider for dynamic holidays:

public class DatabaseHolidayProvider : IHolidayProvider
{
private readonly IHolidayRepository _repository;
public DatabaseHolidayProvider(IHolidayRepository repository)
{
_repository = repository;
}
public IEnumerable<Holiday> GetHolidays(LocalDate from, LocalDate to)
{
return _repository.GetHolidays(from, to);
}
public bool IsHoliday(LocalDate date)
{
return _repository.IsHoliday(date);
}
}
var calculator = new TemporalCalculator(holidayProvider);
// Add positive days (forward)
var future = calculator.AddBusinessDays(today, 10);
// Add negative days (backward)
var past = calculator.AddBusinessDays(today, -5);
// Count business days in a range (inclusive)
var count = calculator.CountBusinessDays(startDate, endDate);
var date = new LocalDate(2024, 12, 25);
var isWorking = calculator.IsBusinessDay(date); // false (Christmas)
// Get next business day (may be today if today is a business day)
var next = calculator.GetNextBusinessDay(date);
// Get next business day (always after given date)
var nextAfter = calculator.GetNextBusinessDay(date, includeToday: false);
var previous = calculator.GetPreviousBusinessDay(date);
// Register in Startup/Program.cs
services.AddSingleton<IHolidayProvider>(sp =>
{
return new StaticHolidayProvider(GetCountryHolidays("US"));
});
services.AddSingleton<TemporalCalculator>();
// Inject in services
public class DeliveryService
{
private readonly TemporalCalculator _calculator;
public DeliveryService(TemporalCalculator calculator)
{
_calculator = calculator;
}
public LocalDate CalculateDeliveryDate(LocalDate orderDate, int businessDays)
{
return _calculator.AddBusinessDays(orderDate, businessDays);
}
}

Common pattern for multi-country support:

public class CountryHolidayProvider : IHolidayProvider
{
private readonly string _countryCode;
private readonly IHolidayDataSource _dataSource;
public CountryHolidayProvider(string countryCode, IHolidayDataSource dataSource)
{
_countryCode = countryCode;
_dataSource = dataSource;
}
public IEnumerable<Holiday> GetHolidays(LocalDate from, LocalDate to)
{
return _dataSource.GetHolidays(_countryCode, from, to);
}
}
// Usage
var usHolidays = new CountryHolidayProvider("US", dataSource);
var ukHolidays = new CountryHolidayProvider("GB", dataSource);
public readonly struct Holiday
{
public LocalDate Date { get; }
public string Name { get; }
public bool IsObserved { get; } // For observed holidays (e.g., Monday after Sunday)
public Holiday(LocalDate date, string name, bool isObserved = false)
{
Date = date;
Name = name;
IsObserved = isObserved;
}
}
public class DeliveryCalculationTests
{
private readonly TemporalCalculator _calculator;
public DeliveryCalculationTests()
{
var holidays = new StaticHolidayProvider(new[]
{
new Holiday(new LocalDate(2024, 12, 25), "Christmas")
});
_calculator = new TemporalCalculator(holidays);
}
[Fact]
public void AddBusinessDays_SkipsWeekend()
{
var friday = new LocalDate(2024, 6, 14); // Friday
var result = _calculator.AddBusinessDays(friday, 1);
result.Should().Be(new LocalDate(2024, 6, 17)); // Monday
}
[Fact]
public void AddBusinessDays_SkipsHoliday()
{
var tuesday = new LocalDate(2024, 12, 24); // Tuesday before Christmas
var result = _calculator.AddBusinessDays(tuesday, 1);
result.Should().Be(new LocalDate(2024, 12, 26)); // Thursday (skips Christmas)
}
}