DateTime.MinValue – be careful!

We’ve just had a support call at work where the user was running our application in Singapore.

Our investigation uncovered an interesting “feature” of using DateTime.MinValue.

Have a look at the following test:

namespace Stuff
{
    using System;
    using NUnit.Framework;

    [TestFixture]
    public class MinDateTimeOffset
    {
        [Test]
        public void Testing_MinValue_in_DateTime()
        {
            Action<string> p = Console.WriteLine;

            // This is Now in the current timezone
            var nowOffset = new DateTimeOffset(DateTime.Now);
            p("Current time:");
            p("- current timezone: " + nowOffset);
            p("- UTC equivilent time: " + nowOffset.ToUniversalTime());
            p("");

            // This is the minimum time allowed in the current timezone
            var minOffset = DateTimeOffset.MinValue;
            p("DateTimeOffset.MinValue:");
            p("- current timezone: " + minOffset);
            p("- UTC equivilent time: " + minOffset.ToUniversalTime());
            p("");

            // This is UTC minimum time
            var minValue = DateTime.MinValue;
            p("DateTime.MinValue:");
            p("- current timezone: " + minValue);
            p("- UTC equivilent time: " + minValue.ToUniversalTime());
            p("");

            // Converted to the current timezone
            try
            {
                p("Trying to cast DateTime.Min to DateTimeOffset:");

                var minDateTimeAsDateTimeOffset = (DateTimeOffset)minValue;
                p("- current timezone: " + minDateTimeAsDateTimeOffset);
                p("- UTC equivilent time: " + minDateTimeAsDateTimeOffset.ToUniversalTime());
            }
            catch (Exception ex)
            {
                p("Error: " + ex.Message);
            }
        }
    }
}

We are based in London, and when we run it, we see this output:


Current time:
- current timezone: 31/10/2012 11:46:35 +00:00
- UTC equivilent time: 31/10/2012 11:46:35 +00:00

DateTimeOffset.MinValue:
- current timezone: 01/01/0001 00:00:00 +00:00
- UTC equivilent time: 01/01/0001 00:00:00 +00:00

DateTime.MinValue:
- current timezone: 01/01/0001 00:00:00
- UTC equivilent time: 01/01/0001 00:00:00

Trying to cast DateTime.Min to DateTimeOffset:
- current timezone: 01/01/0001 00:00:00 +00:00
- UTC equivilent time: 01/01/0001 00:00:00 +00:00

However, when run in Singapore, you get this:

Current time:
- current timezone: 31/10/2012 19:47:38 +08:00
- UTC equivilent time: 31/10/2012 11:47:38 +00:00

DateTimeOffset.MinValue:
- current timezone: 01/01/0001 00:00:00 +00:00
- UTC equivilent time: 01/01/0001 00:00:00 +00:00

DateTime.MinValue:
- current timezone: 01/01/0001 00:00:00
- UTC equivilent time: 01/01/0001 00:00:00

Trying to cast DateTime.Min to DateTimeOffset:
Error: The UTC time represented when the offset is applied must be between year 0 and 10,000.
Parameter name: offset

In New York, you get this :

Current time:
- current timezone: 31/10/2012 07:48:50 -04:00
- UTC equivilent time: 31/10/2012 11:48:50 +00:00

DateTimeOffset.MinValue:
- current timezone: 01/01/0001 00:00:00 +00:00
- UTC equivilent time: 01/01/0001 00:00:00 +00:00

DateTime.MinValue:
- current timezone: 01/01/0001 00:00:00
- UTC equivilent time: 01/01/0001 05:00:00

Trying to cast DateTime.Min to DateTimeOffset:
- current timezone: 01/01/0001 00:00:00 -05:00
- UTC equivilent time: 01/01/0001 05:00:00 +00:00

The value of DateTime.MinValue can not be cast to a DateTimeOffset if you are east of London!

Advertisements

It’s all about TypeScript

I’ve heard several of my friends talking about a new pretender on the block called TypeScript. It’s a language that sits as a superset of  JavaScript, adding static typing, interfaces, classes and more.

As a C# .Net developer, I was very interested to read about what it’s like from a similar point of view. Thankfully, Dave Hanson (@LordHanson) has blogged about a little experimental app he had a go with. Check it out here:

“Cracking a problem with TypeScript”

It looks we all (.Net devs) might be heading in that direction and Microsoft realise that it’ll need to bridge the gap. Looks like a good start. I’m almost excited about coding for the browser again.

Simple Sequences

It’s always interesting coming to a new codebase.

Often you find things that are done in a different way than perhaps you would code it. If you’re lucky, you might find things that are done in a better way than you might have seen before.

Take the opportunity to pass on what you know to your fellow developers and improve the code. And of course to learn everything they have to teach you too!

One simple example I encountered recently is the use of sequences.

Most developers know that arrays and lists (and others) can be treated as IEnumerable, which means that you can use foreach on them.

Often however, it’s easy to miss just how powerful and expressive sequences can be. There is also the often misunderstood yield key word.

What is this Sequence of which you speak?

A sequence can be thought of as taking one item at a time from a line of items. Like sweets from a tube.

You define what happens to each of the items as you take them. For example, you could eat them, or maybe use them to create different items in another sequence.

Let’s have a look at a simple example:

        // <summary>
        // Convert some Models into ViewModels
        // </summary>
        private IEnumerable<ViewModel> CreateViewModels(IEnumerable<Model> models)
        {
            // Create a list to put the new ViewModels in:
            var viewmodels = new List<ViewModel>();

            // Loop over ALL of the models
            foreach (var model in models)
            {
                // Create a new ViewModel:
                var viewModel = new ViewModel(model.Id, model.Name);

                // Add it to the list
                viewmodels.Add(viewModel);
            }

            // finally, return the list of ALL ViewModels
            return viewmodels;
        }

This code is simply taking some Models and converting them into ViewModels.

However, if we think of things as Sequences, then there isn’t any need for the List because we do this:


        // <summary>
        // Convert some Models into ViewModels
        // </summary>
        private IEnumerable<ViewModel> CreateViewModels(IEnumerable<Model> models)
        {
            return models.Select(m => new ViewModel(m.Id, m.Name));
        }

Now there are some very important and subtle differences in these two pieces of code and they’ll become more familiar as you get used to thinking about Sequences.

Lazy Evaluation

No ViewModels are created until the IEnumerable is evaluated. What evaluates a sequence then? Here are some examples of evaluating the sequence.


var viewModels = CreateViewModels(models);

// This pulls each viewModel, one at a time from the sequence.
foreach(var viewModel in viewModels)
{
   ...
}


var viewModels = CreateViewModels(models);

// This pulls each viewModel, one at a time and puts them into an array.
var viewModelsArray = viewModels.ToArray();


var viewModels = CreateViewModels(models);

// This pulls each viewModel, one at a time and puts them into a list.
var viewModelsArray = viewModels.ToList();


var viewModels = CreateViewModels(models);

// This pulls each viewModel, one at a time and counts them.
var viewModelsArray = viewModels.Count();

As you request the ViewModels, the Select statement in CreateViewModels pulls the models from the IEnumerable sequence.

Re-Evaluation

We’ve seen a few examples of calls that evaluate a sequence. Care must be taken to not re-evaluate the sequence repeatly when you don’t mean to.

For example:


var viewModels = CreateViewModels(models);

// The entire sequence must be evaluated to work out the count
var numberOfViewModels = viewModels.Count();

// .. and now we are evaluating the sequence from scratch again
foreach(var viewModel in viewModels)
{
    ...
}

Finally

Before this post gets too long, I’ll finish this post with a few examples of other simple keywords.

Have a think about how much work they are doing, and in particular when they are getting away with doing as little as possible.

var viewModels = CreateViewModels(models);

// This means it only takes one Model and only creates this one ViewModel
var justTheFirstViewModel = viewModels.First();
var viewModels = CreateViewModels(models);

// This means it ignores the first 3, then assigns the value of the fourth one.
// Note that it must fully evaluate (i.e. instantiate) all 4 ViewModels, then though it's ignoring the first 3.
var justTheFourthViewModel = viewModels.Skip(3).First();
var viewModels = CreateViewModels(models);

// Must read all the way through (i.e. instantiate all viewmodels in) the sequence to remember just the last one.
var justTheFourthViewModel = viewModels.Last();