Timecop 2.2.1
See the version list below for details.
dotnet add package Timecop --version 2.2.1
NuGet\Install-Package Timecop -Version 2.2.1
<PackageReference Include="Timecop" Version="2.2.1" />
<PackageVersion Include="Timecop" Version="2.2.1" />
<PackageReference Include="Timecop" />
paket add Timecop --version 2.2.1
#r "nuget: Timecop, 2.2.1"
#:package Timecop@2.2.1
#addin nuget:?package=Timecop&version=2.2.1
#tool nuget:?package=Timecop&version=2.2.1
Timecop - Easy Date and Time Testing in C#
Timecop is a small library that helps to test the code that depends on DateTime by allowing you to freeze and travel in time.
Timecop targets .NET Standard 2.0, has no external dependencies, and can be used with .NET Framework 4.5+ and any version of .NET and .NET Core.
Timecop has been inspired by the timecop Ruby gem.
Installation
You can install Timecop from NuGet using your IDE or the .NET CLI:
dotnet add package Timecop
Basics and usage
To test with Timecop, your code must get the current time using either:
- The
IClockinterface injected as a method or a constructor parameter; - The static
Clockclass.
Usage with the IClock interface
Timecop provides the IClock interface that exposes the Now and UtcNow properties.
Here's how to use it:
- Pass the instance of
IClockto your code as a method or a constructur parameter and use it to get the current time; - In your tests, configure the
Timecopinstance and pass theTimecop.Clockinto the code under test; - When running in production, pass the
IClockimplementaton that returns the current time. You can use the Timecop.Extensions.DependencyInjection package to register such implementation with the DI container in one line of code.
Here's an example:
string Greet(IClock clock)
{
var timeOfDay = clock.Now.Hour switch
{
>= 0 and < 6 => "night",
>= 6 and < 12 => "morning",
>= 12 and < 18 => "afternoon",
_ => "evening"
};
return $"Good {timeOfDay}!";
}
// freeze at 2pm local time:
using var tc = Timecop.Frozen(o => o.At(14,0,0).LocalTime());
Greet(tc.Clock); // Good afternoon!
// travel to 8pm local time:
tc.TravelBy(TimeSpan.FromHours(6));
Greet(tc.Clock); // Good evening!
Usage with the Clock class
Timecop provides the static Clock class that you can use instead of DateTime to get the current local or UTC time. Despite Clock being a static class, it is safe to use in tests that run in parallel as it uses AsyncLocal under the hood.
Here's how to use it:
- Replace the calls to
DateTime.NowandDateTime.UtcNowwithClock.NowandClock.UtcNow; - In your tests, configure the
Timecopinstance
Example:
string Greet()
{
var timeOfDay = Clock.Now.Hour switch // Use Clock instead of DateTime
{
>= 0 and < 6 => "night",
>= 6 and < 12 => "morning",
>= 12 and < 18 => "afternoon",
_ => "evening"
};
return $"Good {timeOfDay}!";
}
// freeze at 2pm local time:
using var tc = Timecop.Frozen(o => o.At(14,0,0).LocalTime());
Greet(); // Good afternoon!
// travel to 8pm local time:
tc.TravelBy(TimeSpan.FromHours(6));
Greet(); // Good evening!
Available methods
Timecop allows to manipulate time in any imaginable way. Freeze time, travel in time, and resume the flow of time with a simple API.
Freezing and resuming time
You can freeze the time so that it stops running for your tests until you call Resume, Reset, or dispose the Timecop instance.
You freeze time with either an instance Freeze or a static Frozen method, both having the same set of overloads. Both methods have the same effect, however the static Frozen creates an already frozen Timecop instance.
using var tc = Timecop.Frozen(1990, 12, 2, 14, 38, 51, DateTimeKind.Local);
Clock.Now; // 1990-12-02 14:38:51
Thread.Sleep(TimeSpan.FromSeconds(3));
Clock.Now; // 1990-12-02 14:38:51 - still the same value
tc.Resume(); // Resumes the flow of time.
Thread.Sleep(TimeSpan.FromSeconds(3));
Clock.Now; // 1990-12-02 14:38:54 - moved 3 seconds forward
Freeze and Frozen have multiple overloads:
// freeze at the current instant:
var frozenAt = tc.Freeze();
// freeze at the specific DateTime:
frozenAt = tc.Freeze(new DateTime(1990, 12, 2, 14, 38, 51, DateTimeKind.Utc));
// freeze at the specific date and time:
frozenAt = tc.Freeze(1990, 12, 2, 14, 38, 51, DateTimeKind.Utc);
// freeze at the specific date:
frozenAt = tc.Freeze(1990, 12, 2, DateTimeKind.Utc);
// freeze at the specific date or time using PointInTimeBuilder:
frozenAt = tc.Freeze(o => o.On(1990, 12, 2)
.At(14, 13, 51)
.InLocalZone());
Traveling in time
Use the TravelBy method to travel forward and backward in time:
using var tc = Timecop.Frozen(1990, 12, 2, 14, 38, 51, DateTimeKind.Local);
tc.TravelBy(TimeSpan.FromDays(1));
Clock.Now; // 1990-12-03 14:38:51 - one day in the future
Use the TravelTo method to travel to the specific point in time:
// travel to the specific DateTime:
traveledTo = tc.TravelTo(new DateTime(1990, 12, 2, 14, 38, 51, DateTimeKind.Utc));
// freeze at the specific date and time:
traveledTo = tc.TravelTo(1990, 12, 2, 14, 38, 51, DateTimeKind.Utc);
// freeze at the specific date:
traveledTo = tc.TravelTo(1990, 12, 2, DateTimeKind.Utc);
// freeze at the specific date or time using PointInTimeBuilder:
traveledTo = tc.TravelTo(o => o.On(1990, 12, 2)
.At(14, 13, 51)
.InLocalZone());
Using PointInTimeBuilder
Freeze, Frozen, and TravelTo methods each accept a lambda that allows to configure the time with the PointInTimeBuilder class.
Use PointInTimeBuilder to specify different components of date and time. When using At and On methods, always specify whether the time is local or UTC using InLocalZone or InUtc.
// When only the date matters:
builder.On(1990, 12, 2).InLocalZone(); // will use the specified date and current time
// When only the time matters:
builder.At(14, 13, 51).InLocalZone(); // will use the specified time and current date
// When neither the date nor time matter, but the date must be in the future or in the past:
builder.InTheFuture();
builder.InThePast();
License
Timecop was created by Dmytro Khmara and is licensed under the MIT license.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. 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 was computed. 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. |
| .NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.0 is compatible. netstandard2.1 was computed. |
| .NET Framework | net461 was computed. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 was computed. net481 was computed. |
| MonoAndroid | monoandroid was computed. |
| MonoMac | monomac was computed. |
| MonoTouch | monotouch was computed. |
| Tizen | tizen40 was computed. tizen60 was computed. |
| Xamarin.iOS | xamarinios was computed. |
| Xamarin.Mac | xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETStandard 2.0
- Timecop.Core (>= 4.2.0)
NuGet packages (1)
Showing the top 1 NuGet packages that depend on Timecop:
| Package | Downloads |
|---|---|
|
Timecop.Extensions.DependencyInjection
Extensions to register Timecop's IClock with IServiceCollection in one line of code. |
GitHub repositories
This package is not used by any popular GitHub repositories.