Time Travel in C#

Imagine if you could control time. Wouldn't that be useful? Especially if you were writing a program to manage artwork in an art gallery, and you wanted to test the part where after two weeks the artwork must be returned to the artist. You could start the program running, add an artwork, hop into the time machine and move two weeks forward and then check that the code works correctly. Of course this is impossible. But fortunately we don't have to do it this way. Instead we can build a bit of cleverness into the way that our program uses dates and times.

Normally a C# program will get a date from the system clock by using DateTime.Now:

artwork.DisplayDate = DateTime.Now;

This sets the display date of my Artwork to the current date and time. My program can then compare the artwork date with future dates to see if more than two weeks have gone by. The snag is that i have to wait two weeks to find out if the code works. So I make something like this:

static class DateSource
{
    public static TimeSpan Offest = new TimeSpan(0);

    public static DateTime Now 
    {
        get
        {
            return DateTime.Now + Offest;
        }
    }
}

This can be used in exactly the same way as the system DateTime class, in that it provides a property called Now which gives a date and time value. But, and this is the useful bit, the date it sends back has an offset applied to it, which I can change. If my program uses DateSource rather than DateTime I can move my program forward (or even backwards) in time simply by changing the offset value:

Console.WriteLine(DateSource.Now.ToString());
DateSource.Offest = new TimeSpan(days:14, hours:0, minutes:0, seconds:0);
Console.WriteLine(DateSource.Now.ToString());

The first statement will print out the current date and time. The second will wind the clock forward 14 days as far as my program is concerned. When we are testing I can add a "wind forwards" button that changes the offset so that I can test my code. I could even change the offset value in a test harness that does this automatically.

This is all part of my "build yourself a nice place to work" philosophy. If your program has to do special things depending on location, don't test it by walking around the countryside. Instead make a program that feeds test coordinates into the location part of the code.