3.5 KiB
EonaCat.DeterministicTime
EonaCat.DeterministicTime is a .NET library for deterministic, testable, and replayable time.
It replaces DateTime.UtcNow, Stopwatch, Timer, and Task.Delay with deterministic equivalents and supports advanced features like:
scheduling, time scaling, replay, NTP offsets, ASP.NET Framework integration. ASP.NET Core integration.
Installation
dotnet add package EonaCat.DeterministicTime
ASP.NET Core integration (optional)
dotnet add package DeterministicTime.AspNetCore
ASP.NET Framework integration (optional)
dotnet add package DeterministicTime.AspNetFramework
ASP.NET 4.8 → add DeterministicTime.AspNetFramework and register HttpModule in web.config:
<system.web>
<httpModules>
<add name="DeterministicTime" type="DeterministicTimeHttpModule"/>
</httpModules>
</system.web>
Basic Usage
using DeterministicTime;
DateTime now = DeterministicTime.UtcNow;
DateTime localNow = DeterministicTime.Now;
Freeze Time
using (TimeScope.Frozen(DateTime.Parse("2025-01-01T00:00:00Z")))
{
Console.WriteLine(DeterministicTime.UtcNow); // frozen
}
Scale Time
using (TimeScope.Scaled(10)) // 10x faster
{
// all timers and delays scale 10x
}
Advance Time Manually
DeterministicTime.Advance(TimeSpan.FromHours(2));
Offset Time
using (TimeScope.Offset(TimeSpan.FromMinutes(5)))
{
// all UtcNow calls are offset by 5 minutes
}
Deterministic Stopwatch
var sw = DeterministicStopwatch.StartNew();
// do work
sw.Stop();
Console.WriteLine(sw.Elapsed);
Deterministic Timer
int fired = 0;
DeterministicTimer.Start(TimeSpan.FromSeconds(10), () => fired++);
DeterministicTime.Advance(TimeSpan.FromSeconds(10));
Console.WriteLine(fired); // 1
Deterministic Delay
bool completed = false;
await DeterministicDelay.For(TimeSpan.FromSeconds(5)).ContinueWith(_ => completed = true);
DeterministicTime.Advance(TimeSpan.FromSeconds(5));
Console.WriteLine(completed); // true
Deterministic Scheduler
var scheduler = DeterministicScheduler.Global;
scheduler.Every(TimeSpan.FromMinutes(1), () => Console.WriteLine("Tick"));
DeterministicTime.Advance(TimeSpan.FromMinutes(5)); // fires 5 times
Time Recording & Replay
Record
using var recording = TimeRecording.Start();
// run code
recording.Save("run.json");
Replay
using (TimeReplay.Load("run.json"))
{
// deterministic replay of UtcNow calls
}
NTP Synchronization
using (NtpSynchronization.Sync(myNtpProvider))
{
// deterministic time aligned with NTP
}
Distributed Time Source
IDistributedTimeCoordinator coordinator = ...;
DeterministicTime.Push(new DistributedTimeSource(coordinator));
Console.WriteLine(DeterministicTime.UtcNow);
ASP.NET Core Middleware
app.UseDeterministicTime();
-
Each request runs in its own deterministic scope
-
Works with frozen/scaled time and timers
Advanced Features Summary
-
Deterministic UtcNow & Now
-
Stopwatch replacement
-
One-shot and repeated timers
-
Task.Delay replacement
-
Time scaling, freezing, offset
-
Scheduler for background jobs
-
Recording & replay for testing
-
NTP synchronization & distributed clocks
-
ASP.NET Framework integration
-
ASP.NET Core integration