Skip to content

Pragmatic.Temporal

Type-safe date/time for .NET 10 with DST-aware arithmetic and explicit timezone handling.

DateTime and DateTimeOffset are ambiguous: DateTime conflates date, time, and zone behind an easily-ignored Kind; DateTimeOffset keeps an offset but not a zone; calendar arithmetic surprises (Jan 31 + 1 month); DST transitions cause silent bugs; and DateTime.Now makes tests flaky.

The type itself defines the temporal scope, and the compiler enforces it. A LocalDate can’t carry time; a ZonedDateTime can’t lose its zone.

using Pragmatic.Temporal.Types;
var birthday = new LocalDate(1990, 5, 15); // date only
var opening = new LocalTime(9, 0); // time only
var appointment = new LocalDateTime(2026, 3, 21, 14, 30); // wall clock, no zone
var flight = ZonedDateTime.FromUtc(DateTimeOffset.UtcNow, "Europe/Rome"); // zone-aware

IClock makes “now” injectable and tests deterministic; calendar arithmetic, business days, and DST transitions are handled correctly.

PackageRole
Pragmatic.TemporalCore types, calendar arithmetic, business days, cron, IClock
Pragmatic.Temporal.JsonSystem.Text.Json converters for all temporal types
Pragmatic.Temporal.EFCoreEF Core value converters, type mapping, conventions
Pragmatic.Temporal.AspNetCoreMiddleware, timezone detection, model binding
Pragmatic.Temporal.TestingTestClock, TestTemporalContext, TestHolidayProvider
Pragmatic.Temporal.InternationalizationCulture-aware display formatting for LocalDateTime/ZonedDateTime via Pragmatic.Internationalization
Terminal window
dotnet add package Pragmatic.Temporal
using Pragmatic.Temporal.Types;
var checkIn = new LocalDate(2026, 6, 1);
var checkOut = checkIn.AddDays(3); // calendar-correct
int nights = checkOut.DayNumber - checkIn.DayNumber;
// Inject IClock instead of DateTime.Now → deterministic tests
public class BookingService(IClock clock)
{
public bool IsPast(LocalDate date) => date < clock.Today;
}

Full walkthrough: Getting Started.

Stable within 1.0.0-alpha — the type set, calendar/business-day arithmetic, DST handling, and the JSON/EF Core/ASP.NET integrations are settled. See the roadmap.

| Concepts | Type = scope, IClock, the mental model, NodaTime comparison | | Getting Started | First temporal types, arithmetic, injecting IClock | | Core Types | LocalDate/LocalTime/LocalDateTime/ZonedDateTime/Duration/… — full reference | | Business Days | Holiday providers, business-day arithmetic, cron | | DST Handling | Ambiguous/non-existent local times, safe conversions | | Testing | TestClock and deterministic time | | JSON Integration | System.Text.Json converters, wire formats, Minimal API setup | | EF Core Integration | Value converters, column mappings, temporal query extensions | | ASP.NET Core Integration | Middleware, timezone detection, model binding | | Common Mistakes | The most frequent date/time pitfalls | | Troubleshooting | Problem/solution guide |

  • .NET 10.0+

Part of the Pragmatic.Design ecosystem — see Licensing. Pragmatic.Temporal is MIT-licensed.