DateTimeOffset: A New DateTime Structure in .NET 3.5 [Justin Van Patten]

One thing we haven't publicized much on this blog yet is a new date time structure we've added in .NET 3.5 called DateTimeOffset (currently available as part of .NET Framework 3.5 Beta 1).  Kathy mentioned it on her blog a while back and Daniel Moth recently posted about it as well.

DateTimeOffset

DateTimeOffset is a new date time data structure that specifies an exact point in time relative to the UTC time zone.  It is made up of a date time and offset relative to the UTC time zone.  DateTimeOffset includes most of the functionality of the current DateTime and allows seamless conversion to DateTime.  DateTimeOffset also works great with TimeZoneInfo which is also new in .NET 3.5.

Samples

1. Creating a new DateTimeOffset:

DateTimeOffset now = DateTimeOffset.Now;

DateTimeOffset now2 = DateTime.Now;

DateTimeOffset now3 = new DateTimeOffset(DateTime.Now);

 

 

DateTime tvShowPremiere = new DateTime(2007, 6, 13, 8, 0, 0);

DateTimeOffset tvShowPremiereUTC = new DateTimeOffset(tvShowPremiere.ToUniversalTime());

DateTimeOffset tvShowPremiereLA = new DateTimeOffset(tvShowPremiere, new TimeSpan(-7, 0, 0));

DateTimeOffset tvShowPremiereNYC = new DateTimeOffset(tvShowPremiere, new TimeSpan(-4, 0, 0));

DateTimeOffset tvShowPremiereLocal = tvShowPremiere; // implicit cast

 

 

DateTimeOffset utcNewYear07 = new DateTimeOffset(2007, 1, 1, 0, 0, 0,

                                new TimeSpan(0, 0, 0));

DateTimeOffset seattleNewYear07 = new DateTimeOffset(2007, 1, 1, 0, 0, 0,

                                    new TimeSpan(-8, 0, 0));

2. Converting a DateTimeOffset to a DateTime:

DateTime dtSeatleNewYear07Utc = seattleNewYear07.UtcDateTime;

DateTime dtSeattleNewYear07Local = seattleNewYear07.LocalDateTime;

3. Parsing a DateTimeOffset:

DateTimeOffset dateA = DateTimeOffset.Parse("4/15/2006 6:00 AM -7:00");

DateTimeOffset dateB = DateTimeOffset.Parse("4/15/2006 6:00:00 AM -7:00");

DateTimeOffset dateC = DateTimeOffset.Parse("-7:00 4/15/2006 6:00 AM");

DateTimeOffset dateD = DateTimeOffset.Parse("4/15/2006 -7:00 6:00 AM");

Usage Guidance

Anthony Moore has some guidance on when to use DateTimeOffset vs. DateTime:

  • Use DateTimeOffset whenever you are referring to an exact point in time.  For example, use it to calculate "now", transaction times, file change times, logging event times, etc.  If the time zone is not known, use it with UTC.  These uses are much more common than the scenarios where DateTime is preferred, so this should be considered the default.
  • Use DateTime for any cases where the absolute point in time does not apply: e.g. store opening times that apply across time zones.
  • Use DateTime for interop scenarios where the information is a Date and Time without information about the time zone, e.g. OLE Automation, databases, existing .NET APIs that use DateTime, etc.
  • Use DateTime with a 00:00:00 time component to represent whole dates, e.g. Date of birth.
  • Use TimeSpan to represent times of day without a date.

As you can see, DateTimeOffset is the new preferred type to use for the most common date time scenarios.  Future BCL APIs will incrementally start to use and take advantage of DateTimeOffset where it makes sense.  This doesn't mean DateTimeOffset is meant to be a replacement for DateTime—DateTime is still useful in the scenarios mentioned above.