RepletoryLib.Utilities.DateAndTime 1.0.0

dotnet add package RepletoryLib.Utilities.DateAndTime --version 1.0.0
                    
NuGet\Install-Package RepletoryLib.Utilities.DateAndTime -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="RepletoryLib.Utilities.DateAndTime" Version="1.0.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="RepletoryLib.Utilities.DateAndTime" Version="1.0.0" />
                    
Directory.Packages.props
<PackageReference Include="RepletoryLib.Utilities.DateAndTime" />
                    
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 RepletoryLib.Utilities.DateAndTime --version 1.0.0
                    
#r "nuget: RepletoryLib.Utilities.DateAndTime, 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 RepletoryLib.Utilities.DateAndTime@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=RepletoryLib.Utilities.DateAndTime&version=1.0.0
                    
Install as a Cake Addin
#tool nuget:?package=RepletoryLib.Utilities.DateAndTime&version=1.0.0
                    
Install as a Cake Tool

RepletoryLib.Utilities.DateAndTime

DateTime provider, business day calculator, South African holidays, fiscal period utilities, and date generators.

Part of the RepletoryLib ecosystem -- standalone, reusable .NET 10 libraries with zero business logic.

NuGet .NET 10 License: MIT


Overview

RepletoryLib.Utilities.DateAndTime provides a comprehensive set of date and time utilities tailored for South African business applications. It includes an injectable IDateTimeProvider for testable time access, a business day calculator that accounts for SA public holidays, fiscal period utilities, recurring date generators, and relative time formatting.

Key Features

  • IDateTimeProvider -- Testable abstraction over DateTime.UtcNow with timezone support
  • Business day calculator -- Add/count business days, skipping weekends and SA public holidays
  • SA public holidays -- Complete holiday calendar with movable holiday support
  • Fiscal period utilities -- Fiscal year, quarter, and period date range calculation
  • Recurring date generator -- Daily, weekly, and monthly date sequences
  • Relative time formatter -- Human-readable time differences ("2 hours ago", "in 3 days")
  • DateRange model -- Range with overlap detection, containment, and date iteration

Installation

dotnet add package RepletoryLib.Utilities.DateAndTime

Or add to your .csproj:

<PackageReference Include="RepletoryLib.Utilities.DateAndTime" Version="1.0.0" />

Note: RepletoryLib packages are published to a local BaGet feed. See the main repository README for feed configuration.

Dependencies

Package Type
RepletoryLib.Common RepletoryLib

Quick Start

using RepletoryLib.Utilities.DateAndTime;

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRepletoryDateAndTime(builder.Configuration);

Usage Examples

IDateTimeProvider

Use IDateTimeProvider instead of DateTime.UtcNow for testable time-dependent code:

using RepletoryLib.Utilities.DateAndTime.Interfaces;

public class SubscriptionService
{
    private readonly IDateTimeProvider _dateTime;

    public SubscriptionService(IDateTimeProvider dateTime) => _dateTime = dateTime;

    public Subscription CreateTrial()
    {
        return new Subscription
        {
            StartDate = _dateTime.UtcNow,
            ExpiresAt = _dateTime.UtcNow.AddDays(30),
            Today = _dateTime.Today
        };
    }

    public DateTime GetLocalTime()
    {
        return _dateTime.Now("Africa/Johannesburg"); // SAST
    }
}

Business Day Calculator

using RepletoryLib.Utilities.DateAndTime.Services;

var calculator = new BusinessDayCalculator();

// Add 5 business days (skips weekends and SA public holidays)
var startDate = new DateTime(2025, 12, 22); // Monday before Christmas
var deadline = calculator.AddBusinessDays(startDate, 5);
// Skips Dec 25 (Christmas), Dec 26 (Day of Goodwill), weekends

// Check if a date is a business day
bool isBusinessDay = calculator.IsBusinessDay(new DateTime(2025, 4, 18)); // Good Friday -> false

// Count business days between two dates
int workingDays = calculator.GetBusinessDaysBetween(
    new DateTime(2025, 1, 1),
    new DateTime(2025, 1, 31));

South African Public Holidays

using RepletoryLib.Utilities.DateAndTime.Data;

// Get all SA public holidays for a year
var holidays2025 = SaPublicHolidays.GetHolidays(2025);
// Returns: New Year's Day, Human Rights Day, Good Friday, Family Day,
//          Freedom Day, Workers' Day, Youth Day, National Women's Day,
//          Heritage Day, Day of Reconciliation, Christmas Day, Day of Goodwill

// Check if a specific date is a public holiday
bool isHoliday = SaPublicHolidays.IsPublicHoliday(new DateTime(2025, 6, 16)); // Youth Day -> true

Fiscal Period Utilities

using RepletoryLib.Utilities.DateAndTime.Services;

var fiscal = new FiscalPeriodHelper();

// South African fiscal year starts March 1 (default startMonth = 3)
int fiscalYear = fiscal.GetFiscalYear(new DateTime(2025, 6, 15)); // FY2025
int fiscalQuarter = fiscal.GetFiscalQuarter(new DateTime(2025, 6, 15)); // Q2

// Get the date range for a fiscal year
var range = fiscal.GetFiscalPeriodDates(2025, startMonth: 3);
// range.Start = 2025-03-01, range.End = 2026-02-28

Recurring Date Generator

using RepletoryLib.Utilities.DateAndTime.Services;

var generator = new RecurringDateGenerator();

// Generate 12 monthly dates (e.g., for billing)
var billingDates = generator.Monthly(
    start: new DateTime(2025, 1, 1),
    dayOfMonth: 25,
    count: 12);
// 2025-01-25, 2025-02-25, ..., 2025-12-25

// Generate weekly dates (e.g., for meetings)
var meetings = generator.Weekly(
    start: new DateTime(2025, 1, 6),
    day: DayOfWeek.Monday,
    count: 52);

// Generate daily dates
var dailyReports = generator.Daily(
    start: new DateTime(2025, 1, 1),
    count: 30);

Relative Time Formatter

using RepletoryLib.Utilities.DateAndTime.Services;

var formatter = new RelativeTimeFormatter();

formatter.Format(DateTime.UtcNow.AddMinutes(-5));  // "5 minutes ago"
formatter.Format(DateTime.UtcNow.AddHours(-2));    // "2 hours ago"
formatter.Format(DateTime.UtcNow.AddDays(-1));     // "yesterday"
formatter.Format(DateTime.UtcNow.AddDays(3));      // "in 3 days"

DateRange Model

using RepletoryLib.Utilities.DateAndTime.Models;

var q1 = new DateRange(new DateTime(2025, 1, 1), new DateTime(2025, 3, 31));
var feb = new DateRange(new DateTime(2025, 2, 1), new DateTime(2025, 2, 28));

q1.Contains(new DateTime(2025, 2, 15)); // true
q1.Overlaps(feb);                       // true
q1.Duration;                            // 89 days

// Iterate all dates in range
foreach (var date in feb.ToDates())
{
    Console.WriteLine(date.ToShortDateString());
}

API Reference

Type Description
IDateTimeProvider UtcNow, Today, Now(timezone)
BusinessDayCalculator AddBusinessDays, IsBusinessDay, GetBusinessDaysBetween
FiscalPeriodHelper GetFiscalYear, GetFiscalQuarter, GetFiscalPeriodDates
RecurringDateGenerator Daily, Weekly, Monthly
RelativeTimeFormatter Format(from, to?)
SaPublicHolidays GetHolidays(year), IsPublicHoliday(date)
DateRange Contains, Overlaps, Duration, ToDates

Integration with Other RepletoryLib Packages

Package Relationship
RepletoryLib.Common Direct dependency; DateTimeExtensions complement this package
RepletoryLib.Data.Interceptors [StoreAsUtc] and [DisplayInTimezone] attributes
RepletoryLib.Testing MockDateTimeProvider for deterministic time in tests

Testing

Use MockDateTimeProvider from RepletoryLib.Testing:

using RepletoryLib.Testing;

[Fact]
public void Trial_expires_in_30_days()
{
    var mockTime = new MockDateTimeProvider(new DateTime(2025, 1, 1));
    var service = new SubscriptionService(mockTime);

    var subscription = service.CreateTrial();

    subscription.ExpiresAt.Should().Be(new DateTime(2025, 1, 31));

    mockTime.Advance(TimeSpan.FromDays(31));
    // Now UtcNow is 2025-02-01 -- subscription has expired
}

Troubleshooting

Issue Solution
Business day calculation wrong Verify the year's holidays with SaPublicHolidays.GetHolidays(year)
Fiscal year off by one The default startMonth is 3 (March). Adjust for your fiscal calendar.
IDateTimeProvider not injectable Ensure AddRepletoryDateAndTime is called in service registration

License

This project is licensed under the MIT License.

Copyright (c) 2024-2026 Repletory.


For complete documentation, infrastructure setup, and configuration reference, see the RepletoryLib main repository.

Product Compatible and additional computed target framework versions.
.NET net10.0 is compatible.  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 (1)

Showing the top 1 NuGet packages that depend on RepletoryLib.Utilities.DateAndTime:

Package Downloads
RepletoryLib.Testing

Test helpers, mocks, and base classes for RepletoryLib

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.0.0 73 3/2/2026