Why Not Add a New DateTime Date Type in Whidbey?

Why Not Add a New DateTime Date Type in Whidbey?

  • Comments 20

[Anthony Moore]

Thanks very much to those who have posted feedback on this issue:


This reply to the feedback got quite lengthy, so I started a new entry on it.

>> "You COULD have seen and SHOULD have seen this"

We would definitely agree that this is a bad situation and we should have seen this in the first version of the product. The toughest bit is that for the V1.0 and V1.1 products, it is hard for us to even provide good guidelines for completely reliable DateTime scenarios. Although there is dissatisfaction that the currently Whidbey plan is sufficient, it does at least allow for guidelines to be created that can actually be followed.

Three replies emphatically ask that we consider adding a complete new DateTime type in Whidbey that is UTC internally. It is probably worth sharing some of the existing discussion on this point.

Once the full extent of the DateTime problems were understood, a great many options for correcting it were considered. These included changing the implementation to be UTC internally and deprecating the existing data type and replacing it with a completely new one.

It sounds like people are bought into the notion that retroactively changing the internal implementation of the current DateTime to always be UTC and also staying sufficiently compatible accross versions is not possible. This option was thoroughly explored and was a plan of record for a brief time until all the compatibility issues with it were fully explored.

Another option explored was switching over every API that returned a Local instance to returning a UTC instance. Of the 84 APIs that took or returned DateTime in the V1.0 NDP, this would have involved deprecating 81 of them, and replacing them with versions that had an identical signature, but a DateTime instance that was UTC instead of local. This would have created a lot of disruption to owners and consumers of the APIs alike. We would need a very good reason to do this. It was seen as preferable if there was a way allow people to get reliable behavior without having to switch every call involving a DateTime over to using a different API.

This lead to the current plan of record, which is compatible enough to allow existing APIs to get the extra reliability without needing to change either the signature or meaning of their results.

The option of deprecating DateTime and replacing it has many of the same undesirable consequences. More than just deprecating the type istelf, you are then making every API that takes or returns the API obsolete and making it a requirement to switch over to somthing new. We could do this, but we would need a very good reason and a lot of lead time. Given that it was possible to solve the key reliability problem by just making the Local->UTC conversion non-lossy, this was seen a better alternative.

It is suggested that there is still time in Whidbey to add a new DateTime. Actually, there probably is enough time to add such a new type. However, I could get it to you even more quickly by sending you a sample, and it would be no less useful. The reason is that while there may be time to add this new data type, there is not the time to integrate it anywhere near as deeply as you would want. You would need to integrate it with Remoting, Serialization, XML Serialization, the Debugger, XML Convert, Type Converters, etc. etc. You would also want to add several hundred new APIs in technologies like ASP.NET and System.Net to provide versions of their APIs that would accept this new type. There is not enough time to get this level of integration with the rest of the product, so if we did add this type, it would not be of much more use than some sample code.

Given the cost of actually trying to replace something as widely used as DateTime, it is not even clear if it is a good option long term. Part of the value of the .NET Framework is the standardization and simplicity in having, for example, just one way to represent a string. A 2nd DateTime type would erode that and would need a very compelling reason to exist.

A more likely option is that there might be a sort of supplemental time type that is not destined to replace DateTime, but to interoperate well with it, and to be recommended for scenerios where you are doing cross-time-zone stuff. Part of the problem here also is that this is tied to another large work item, which is time zone enumeration. This is quite an expensive work item for us, as outlined in the DateTime FAQ: http://www.gotdotnet.com/team/clr/bcl/TechArticles/techarticles/DateTimeFAQ/FAQ.aspx

This will probably sound defensive and adverserial. Believe me, I don't see this as a good situation and I have actually asked all these same questions you are asking now many times, and we have tried to thoroughly explore them all. But we do feel that the current solution for Whidbey draws the best line between fixing unreliable usage, maintaining compatability across versions and keeping the framework simple and consistent.

I look forward to further discussion of this issue.

  • Seems that it is rather late to switch from local time to UTC time, and that it would create too much disruption.

    What we really need, especially on server applications is a much richer TIMEZONE API. If we could enumerate and query timezones, and also associate a timezone to the current thread (so that datetime values are formatted and parsed according to the thread's timezone), then it would be much easier to develop servers that adapt their date and time formatting rules to the user's location.

    Unlike switching from locale time to UTC, this change (introducing thread level timezone + formatting and parsing according to the thread's timezone rather than the computer's timezone) does not break compatibility with what we have today (as long as the thread's timezone coincides with the computer's timezone by default). So, rather than break what works today, extend it!

    Also, you get my vote for separate Date and Time datatypes.
  • Anthony,

    I should have been clearer in my post. When I said

    "We can (and will) code our own implementation [of a UTC based DateTime type]"

    I was thinking not only of storing DateTime as UTC internally, but also of converting from/to local time (or from/to some arbitrarily specified time zone). I can't go into the specifics, but this can be (and often is) a critical feature to our apps. We will probably use our own implementation anyway, but having this built in would mean one less issue to deal with in converting to the .NET Framework.
  • As I said before, I think separate classes for DateTime and UtcDateTime make sense, and I think at least some sort of UtcDateTime should be in Whidbey (or at least in a service pack or separate download soon thereafter). I also agree that a timezone-aware date/time class would be useful (maybe the same class as one of the above, maybe not), as would a date-only class and a time-only class. I'll also throw in a suggestion for a class that only contains month and year (no day). Obviously, these should all be immutable value types.

    (Hey, is there going to be a Mutable<T> type for making a mutable reference-type wrapper for immutable value types?)

    I think these different date classes would all be useful. But the more I think about it, the more I think there would also need to be an IDateTime interface that all of these implement, so that library developers wouldn't necessarily *have* to care which type they're dealing with in all cases (but could still specify if needed).
  • Why not have an instance variable on DateTime that is "isUTC"? It would mean that calling DateTime.ToUTC would only do the conversion once, and would eliminate a whole class of off-by-N-hours bugs.

    DateTime x = some-local-time (e.g. filetime)
    DateTime y = x.ToLocalTime();
    DateTime z = x.ToUTC();
    DateTime w = z.ToUTC();

    This won't fix the multiple timezone problems, but it will make DateTime a bit more intelligent without requiring a whole new sub-system. isUTC defaults to false, thus preserving the existing semantics except in the error cases (i.e. ToUTC called multiple times)

    This also lets you generate UTCDateTime objects with a bit more reliablity.

    DateTime loc = filetime or something
    UTCDateTime utc = loc.ToUTCDateTime();
    DateTime x = loc.ToUTC();
    Assert.IsTrue( utc == x );
    DateTime y = x.ToLocal();
    DateTime z = utc.ToLocal();
    DateTime w = utc.ToTimeZone(curZone);

    Also +1 on the UnixTime functions mentioned above. Alternatively add a converter class to help simplify the transmogrification.

  • While doing my System.DateTime and System.TimeZone investigation, I come across some old discussions...
Page 2 of 2 (20 items) 12