Abstracting the DateTime.Current dependency
Asked Answered
M

3

8

Is there a nuget package, or other "standard" that wraps the hard dependency created when your code is coupled to DateTime.Now?

I'm seeking guidance on this before writing my own. Albeit that it's trivial to do so, I'd rather use something that exists if it already does as somewhat of a standard.

Morsel answered 21/10, 2011 at 15:18 Comment(1)
@Jason: Avoiding the implicit dependency here is thoroughly worthy. Getting "the current time" is a service like any other dependency. It's so much easier to test code which makes that clear.Erdmann
M
0

Suppose we have a method:

public void Foo() {

  var now = DateTime.UtcNow;
  Record(now);      

The solution i always employ anytime I need DateTime.Now is:

public void Foo(DateTime? now = null) {

  Record(now.GetValueOrDefault(DateTime.UtcNow));
Morsel answered 31/7, 2015 at 17:35 Comment(0)
E
3

I very much doubt that there's any nuget package for anything quite so trivial - a single interface and probably two implementations ("system" clock and a fake one for testing).

If you're doing one of these yourself, I would strongly consider making the clock return a DateTimeOffset instead of a DateTime, or at least make it wrap DateTime.UtcNow... DateTime.Now is a problem waiting to happen...

However, Noda Time contains all of this out of the box. You probably don't want the whole of Noda Time just for this reason, mind you...

(There's a Noda Time nuget package, but it's definitely pre-release. I need to update it to a 0.2 version at some point, but it's still not at the v1 level yet. Getting there though...)


If you want a really cheap-and-cheerful way of expressing the dependency, you could always take a Func<DateTime> or Func<DateTimeOffset> wherever you normally express dependencies. The interface approach is cleaner though :)

Erdmann answered 21/10, 2011 at 15:22 Comment(2)
Could you elaborate on why you would recommend using a DateTimeOffset? I don't believe I've ever had a need to use that class before. Also I took a look at Noda Time and I didn't really see much in usage examples, is there a specific something I should look at to start with?Morsel
@ChrisMarisic: DateTimeOffset is rather less ambiguous than DateTime, which is a pain to work with in terms of having to check whether it's local or universal etc. I don't have many usage examples for Noda Time yet, but if you have a specific operation in mind, I'm happy to write that up as an exmaple (or several). Putting up real examples would be fabulous :)Erdmann
J
1

I dont know of any nuget package that does this. When I've run into this problem I've simply created my own type like this:

public static class SystemTime
{
    public static Func<DateTime> Now = () => DateTime.Now;
}

That way in your unit tests you can easily change the functionality of Now to return any DateTime you want.

Justitia answered 21/10, 2011 at 15:21 Comment(2)
Ick - can't say I like that approach myself. This is a dependency - so make it obviously a dependency.Erdmann
-1 this is taking the core DateTime.Now dependency and making exactly DateTime2.NowMorsel
M
0

Suppose we have a method:

public void Foo() {

  var now = DateTime.UtcNow;
  Record(now);      

The solution i always employ anytime I need DateTime.Now is:

public void Foo(DateTime? now = null) {

  Record(now.GetValueOrDefault(DateTime.UtcNow));
Morsel answered 31/7, 2015 at 17:35 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.