DateTime, DateTimeOffset and Timezones

Jul 23, 2009 at 8:41 AM

Time is so scary and I am always thrilled by it.
So I've been wondering, how Savant handles DateTime objects. Especially when it comes to timezones.

For example putting DateTime.Now results in "2009-07-23T09:31:39.358+02:00" while putting DateTime.UtcNow in "2009-07-23T07:31:39.358+02:00". Since Savant appends the computer's (?) timezone, not to mention daylight savings as I am sitting in UTC+1 which is UTC+2 right now, I'm pretty sure it gets really ugly when searching and ordering by time because of the lexicographical ordering in SDB.
For my particular case however, I don't even need timezone information and would prefer that putting UtcNow would result in "2009-07-23T07:31:39.358Z". One could then save the timezone offset as separated attribute, if required.

I understand that in .NET 3.5 (and SQL Server 08) the new DateTimeOffset object handles timezones much better, however Savant currently doesn't support it. Furthermore I wouldn't have a clue how to serialize it as string in an orderable way. I doubt this is even possible.

Maybe I just don't get it. Thanks for any input on this.

Coordinator
Jul 23, 2009 at 2:29 PM
Edited Jul 23, 2009 at 2:31 PM

Right now the built-in date formatting is fairly simplistic. But sorting and searching should work fine except for times that "overlap" because of the daylight-savings rollback from 2:00 AM to 1:00 AM each fall.

If you need anything more sophisticated or tailored to your needs you have a couple of options: you can apply a CustomFormatAttribute to your date fields with the desired format string or for even more control define a custom type formatter (implement ITypeFormatter) and apply it with (again) CustomFormatAttribute. The API documentation has more details on how to do this. Here's a simple example:

public class MyEntity {
  // Date format with no timezone
  [CustomFormat("yyyy-MM-ddTHH:mm:ss.fff")]
  public DateTime MyDate {get;set;}

  // custom type formatter
  [CustomFormat(typeof(MyDateFormatter))]
  public DateTime MyDate2 {get;set;}
}

public class MyDateFormatter : ITypeFormatter  {

  public string ToString(object value)
  {
    return value.ToString();
  }

  public object ToType(string value, Type expected)
  {
    return new DateTime(value);
  }
}

Coordinator
Aug 21, 2009 at 3:57 PM

After taking another look at this, it looks like the right answer is to use the "K" formatter which replaces the timezone with a "Z" for UTC times. I've updated the issue created for this change:

http://simplesavant.codeplex.com/WorkItem/View.aspx?WorkItemId=3596