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.

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.

In C# that is true, but certainly not in all other languages. Try to compile the following IL into a DLL.

.assembly Testing {}

.namespace Foo

{

.class public sequential unicode sealed beforefieldinit MyStruct

extends [mscorlib]System.ValueType

{

}

.class public sequential unicode sealed beforefieldinit MyStruct2

extends [mscorlib]System.ValueType

implements Foo.MyStruct

{

}

}

You may then use it from C#. (And I encourage you to examine the DLL in Reflector.)

There really is a strong need for a UTC-only DateTime type. Unsealing the type would be sufficient as I am comfortable writing IL. However, an interface is ultimately the better option. All of these new types being added in Orcas is only adding further complication without truely solving the real problem.

A default DateTime is broken 100% of the time. Every single time it will need to be manually set to be UTC. Any exceptions, probably accidental, and often even due to ignorance or poor design, is a bug to be found and fixed. I have fixed dozens of these bugs over the last six years at several different companies. I have created wrapper types to help solve the problem. However, the best that can be done is wrap DateTime because it can not be extended and there are no interfaces to implement. I have also created my own non-wrapper types that provide the necessary functionality. However, it does not fit into the framework because of incompatible signatures.

While I have had many unpleasent encounters with this type in particular, the source of the problem is very prevalent throughout the BCL: 1) sealed types and 2) no interfaces. You can do better than this.

I am perfectly fine if Microsoft does not want to provide the functionality. But let me. To integrate that into the BCL, though, I will need to be able to either extend the type or implement an interface (appropriate signatures will need to take interface, the implementation).

We currently have the DateTimeMode property to control serialization of dateTimes from datasets. Although it has limitations, like you can’t set it after you’ve loaded any rows, so it’s a pain for untyped datasets – need to call FillSchema then Fill. And there were bugs with typed datasets – some claim these still aren’t fixed in SP1 – see http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=208033&SiteID=1

So, will Datasets allow columns of type DateTimeOffset ? How would that work for untyped datasets where columns are created on the fly based on the SQL statement – do we need a "create dateTimes as DateTimeOffset’s" property ? And could we specify a default timezone like UTC, or allow that to be picked up from a database column ? Whilst Oracle has a timestamp with timezone datatype which could map straight to DateTimeOffset, SQL Server doesn’t, so how could we set default timezones in that case ?

I don’t want to get into discussion about whether datasets are evil or not (personally I use objects) but lots of developers do use datasets, so it needs considering.

ILAsm compiles your Foo valuetype as sealed (even you do not mark it as sealed). If you compile it with "The Monster Flag" (/errors), you can create an unsealed value type. BUT such metadata are invalid. I hope Loader will refuse the assembly…