'Why there is no IDateTimeProvider in .NET and DateTime has Now getter?

Currently I'm writing a unit test for a component that does datetime specific validation. I have created IDateTimeProvider interface, that serves as a DateTime.UtcNow wraper and business objects use interface rather than DateTime directly. It seems that DateTime is a bit overloaded and should be split into a value and a thing that gets that value from the OS. I wonder if there is a particular reason not to have a IDateTimeProvider (IClock) interface in .NET?



Solution 1:[1]

We consistently use a DateTimeProvider wrapper class which we can override in a test context if necessary...

Solution 2:[2]

http://learn.typemock.com/typemock-isolator/ is able to mock DateTime (and other mscorlib types) so DateTime.Now isn't an issue again. But the disadvantage is of course that this may lead developers design their stuff more poorly since it is no problem to mock DateTime.Now!

Maybe using something like IDateTimeProvider is a better solution for such things.

But if you're using a third-party lib that relays on e.g. DateTime TypeMock-Isolatior maybe a solution/workaround.

Also Microsoft Research's Moles/Stub is cool stuff: http://channel9.msdn.com/blogs/peli/moles-replace-any-net-method-with-a-delegate (shows how to replace any .NET method/property with a delegate - e.g. DateTime.Now ;-))

Solution 3:[3]

I posted this answer to another question, but it applies here too if you're looking for a simple way to test DateTime.Now.

What I like to do is create a public function that returns a DateTime (Func<DateTime>) in the class that needs the current date/time and set the it to return DateTime.Now by default. Then, during testing, I overwrite it with a testing function that returns whatever DateTime I want to test with.

public class MyClass
{
    public Func<DateTime> DateTimeNow = () => DateTime.Now;

    public void MyMethod()
    {
        var currentTime = DateTimeNow();
        //... do work
    }
}

public class MyClassTest
{
    public void TestMyMethod()
    {
        // Arrange
        var myClass = new MyClass();
        myClass.DateTimeNow = () => new DateTime(1999, 12, 31, 23, 59, 59);

        // Act
        myClass.MyMethod();

        // Assert
        // my asserts
    }
}

Solution 4:[4]

There's a few alternatives that work out of the box now:

I'd use the first one. Even though its namespace suggests it's used internally. It is documented and publicly available. It only has a method to get the current UTC time, but I wouldn't want to make my server timezone dependent anyway.

Of course, there's been a few improvements in datetime handling, so we now have a quite a few types at our disposal.

  • We already had DateTime, TimeSpan, TimeZoneInfo, DateTimeInfo
  • We now have DateOnly, TimeOnly

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Koen
Solution 2
Solution 3 Matt Klein
Solution 4 realbart