What’s In Your Date?

August 28, 2014

So you’re developing a new enterprise application and everything is working. You have the clients talking to front end servers; front end servers routing data through your app tiers down to your database and storage systems; and all of this through a complex series of firewalls and SSL. Unfortunately, this is your development environment. QA and Prod are getting weird, and different, results. Some dates are off by a day, some are off by hours. Some functionality simply fails because of concurrency issues. Some things work on some browsers but not others. Some clients randomly explode.

Welcome to DateTime hell. 

Here is my attempt at wrangling some of these issues in.

Most people use the DateTime field type in SQL Server; after all, you are storing a DateTime … right? Nope. DateTimes in SQL server don’t store any time zone information. They store it as local time to the server. This works fine when your app servers and your database server exist in the same time zone. But, when they don’t … just use the DateTimeOffset field type instead. Start your database with the right field values and avoid the headache.

Moving up to the app tier: .NET
.NET actually does a pretty good job of handling DateTimes. It has time zone awareness built in; it knows that it doesn’t know the time zone (As opposed to other languages / systems assuming a time zone).
See Microsoft Developer Network.
Unfortunately, even .NET has DateTime issues and it’s around transmission of the DateTime to other tiers. For example, say you expose the date via a web service so that the client can consume it. By default it gets serialized as \/Date(1234567890)/. Not knowing what that is you Google it. Turns out it’s the number of milliseconds since January 1st, 1970. As an added bonus it’ll only accept dates in that format. Good news is that there is a workaround. You can specify your own contract and customize the serialization and deserialization:

public DateTime LastModifiedDateTime { get; set; }

[DataMember(Name = "LastModifiedDateTime")]

private string LastModfiedDateTimeString

{

get

{

return this.LastModifiedDateTime.ToUniversalTime().ToString("s") + "Z";

}

set

{

this.LastModifiedDateTime = DateTime.Parse(value);

}

}

And finally the client tier: Javascript
This one is probably the worst. Who would have thought that Javascript months start at 0 and getDay() returns the day of the week? Moreover, different browsers parse date strings returned from the app tier differently. So, you’re required to come up with a custom parser. Or let someone else deal with it and use a 3rd party library.

And this is just the start. I didn’t mention:

  • Different date formats
  • Dates without times (Since these are datetimes)
  • Lack of support for ‘Z’ in the ISO 1806 standard
  • Altering your local time zone format
  • Non-gregorian calendars
  • Crazy off-standard time zones
  • Living in space
  • Living on another planet where a day isn’t 24 hours
  • Traveling at relativistic speeds

Conclusion

DateTimes and time zones are a nightmare. Don’t attempt to solve Date issues by yourself. Let someone else lose their sanity trying to deal with all of the issues. And, if you think you have it tough, well, I’ll let someone else explain the insanity.