---
title: "Time abstraction in .NET 8"
description: "With the upcoming release of .NET, the team introduced an abstraction of time itself. That can bring you major benefits especially if you have to test scenarios where time is a crucial part! Until now, you had to create your own wrapper. This, of course, makes integration with 3rd party libraries tricky."
updated: 2023-06-04
tags: [".NET 8", ".NET", "C#"]
canonical: "https://steven-giesel.com/blogPost/4d5b70fe-35c1-43c7-bebe-49194195ffcb/time-abstraction-in-net-8"
---

# Time abstraction in .NET 8

With the upcoming release of .NET, the team introduced an abstraction of time itself. That can bring you major benefits especially if you have to test scenarios where time is a crucial part! Until now, you had to create your own wrapper. This, of course, makes integration with 3rd party libraries tricky.

## Your custom wrapper
Until now, you had to rely on your own wrapper to make time somewhat predictable in your tests. If you had ever experienced like: `DateTime.UtcNow` or friends that can become a pain during your tests. What people, including me, did:
```csharp
public interface ITimeProvider
{
    DateTime UtcNow { get; }
}

public class TimeProvider : ITimeProvider
{
    public DateTime UtcNow => DateTime.UtcNow;
}
```

That is nice and works, but it seems odd to do this everytime again. Also that doesn't work with 3rd party libraries that use `DateTime.UtcNow` directly. You can't mock that easily.

## `TimeProvider`
The new abstract classes build a base on which you can build your own time provider. It has a `SystemTimeProvider` that is the default implementation.

Imagine you have a function that does something like this `await Task.Delay(TimeSpan.FromSeconds(5));`, well obvious you don't want to wait 5 seconds in your tests. So Microsoft added new overloads for many APIs that have a time component:

```csharp
public static Task Delay(TimeSpan delay, TimeProvider provider, CancellationToken cancellationToken = default);
```

So we have the chance to say how time flows in our tests! Let's see how we can use that:
```csharp
var timer = new NoWaitingTimeProvider();

Console.WriteLine("Entering Task.Delay at " + timer.GetUtcNow());
await Task.Delay(TimeSpan.FromSeconds(5), timer);
Console.WriteLine("Exiting Task.Delay at " + timer.GetUtcNow());

public class NoWaitingTimeProvider : TimeProvider
{
    public override ITimer CreateTimer(
        TimerCallback callback,
        object? state,
        TimeSpan dueTime,
        TimeSpan period)
    {
        return base.CreateTimer(callback, state, TimeSpan.Zero, period);
    }
}
```

In this case we create a `TimeProvider` that has no `dueTime` or better the `dueTime` is set to `TimeSpan.Zero` so whatever we pass in, the timer is directly done! This is a very simple example, but you can imagine that you can do a lot more with this. Imagine you want to tests your retry logic, you can now control how time flows making your tests more reliable and faster!

And of course, the example I showed above is also manageable with the new `TimeProvider` as it offers a `GetUtcNow` method that you can override.

## There is more
I showed a version where I implemented my own version of the `TimeProvider` but of course, you don't have to do that! `TimeProvider` is an `abstract` class where every function is `virtual` making it a prime candidate for mocking frameworks. So you can easily mock every aspect!

## Conclusion
The new `TimeProvider` is a great addition to the .NET framework. It makes testing scenarios where time is a crucial part a lot easier and more reliable.