Why Not Add a New DateTime Date Type in Whidbey?
[Anthony Moore]
Thanks very much to those who have posted feedback on this issue: https://weblogs.asp.net/bclteam/archive/2004/05/21/136918.aspx
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: https://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.
Comments
- Anonymous
June 01, 2004
"simplicity in having, for example, just one way to represent a string"
Bad example. See http://weblogs.asp.net/shawnfa/archive/2004/05/27/143254.aspx - Anonymous
June 01, 2004
We just went through these problems, and decided to roll our own DateTime class with the appropriate behavior.
We also recognized another serious shortcoming to the DateTime class; that is, that a time is always required. Sometimes you just want a Date without a time, and then without timezone considerations. Having a specific type for a timeless and timezoneless Date was a pretty significant win for us. - Anonymous
June 01, 2004
In the long run, I think that adding a separate type, and deprecating the non-timezone-aware DateTime, would be by far the best solution, even if it would be labor-intensive.
In the short run (Whidbey timeframe), why not take steps in that direction? Include a UtcDateTime class in the Whidbey BCL, integrate it superficially with a handful of APIs, and suggest (without actually deprecating the old one) that customers -- and third-party library vendors -- start using the new UtcDateTime instead of DateTime. Nobody will be able to use it fully, since few APIs will support it yet, but developers will have plenty of lead time to start migrating parts of their code toward a UtcDateTime. Then the next (post-Whidbey) Framework could officially provide deep support for UtcDateTime and deprecate the old DateTime.
If there was a standard UtcDateTime class that everybody could use, third parties and open-source developers would quickly move to fill the gaps in the APIs. Just having that standard class (like the example you gave of a standard String class) would go a long way toward solving the problem in the short term, as well as being a good start toward a long-term solution.
(BTW, I like Brad's idea of a date-only type with no timezone awareness... put my vote in for adding one of those someday.) - Anonymous
June 01, 2004
Halfway through my comments, I noticed that Joe White had already written what I was trying to convey, and had done a much better job at it.
I strongly agree that in the end we will need another type ("UtcDateTime" or whatever it will be called). It could live side-by-side with the current DateTime. There is no need to depreciate DateTime at this time; let it be to support the existing APIs. Over time (hopefully partly during the Whidbey timeframe and more during Orcas), the types that work with the existing DateTime type can be extended to work with the new "UtcDateTime". - Anonymous
June 01, 2004
If you can't make the current DateTime work, then add a new one that does work. If you know the problem and choose to ignore it (or even worse, acknowledge it and not fix it) then you have done the Wrong Thing. "It is a lot of work" is not a good excuse for something as important as this. - Anonymous
June 02, 2004
++ to the other comments.
A UTC based/aware DateTime type is a necessity for the projects I work on. We can (and will) code our own implementation when the time come for us to fully use .NET, but this issue may be a sticking point on how quickly we go to full use. - Anonymous
June 02, 2004
Would it not be possible to add a property to the existing DateTime class of a type which is TimeZone (e.g. ActiveTimeZone), default this to TimeZone.CurrentTimeZone (for backwards compatability) and introduce a TimeZone.UTC static property (on the TimeZone object) which you could set the ActiveTimeZone property on the DateTime class to, resulting in the DateTime class using UTC? - Anonymous
June 03, 2004
I added a new post as a reply to this feedback:
http://weblogs.asp.net/bclteam/archive/2004/05/21/136918.aspx
In short:
Q: Why Not Add a New DateTime Date Type in Whidbey?
A: Because after two decades Microsoft still does not understand the problem (yet tries to provide a "solution") - Anonymous
June 04, 2004
The comment has been removed - Anonymous
June 08, 2004
The comment has been removed - Anonymous
June 09, 2004
The comment has been removed - Anonymous
June 11, 2004
Thanks, Keith.
I have been thinking about that very problem. It depends on how the design comes out, and primarily whether you store a time zone ID in addition to the offset. If you don't have the ID, then you end up with times that are precise and presentable, but you couldn't distinguish, for example, between Perth times and Singapore times, which often have the same offset but have different daylight savings rules. Without knowing this you could not adjust appropriately through arithmetic, or preserve the informaiton for its own sake. This might not be a show-stopper.
Even then you would have to be very careful to enable forward compatability on the serialization so that you could potentially add time zone ids later, and then you might be forced to make any behavior that keys off this new information opt-in for compatability reasons, as we must do for the current Whidbey DateTime changes.
This feedback, combined with some other discussions with internal teams in the last few weeks, is leading us to consider the question of whether there will be a new DateTime and what it will look like sooner rather than later. We are trying to put a plan together in the next couple of months, because we definitely want to make this better in Longhorn if we can. What might fall out of this is a decision to have a new type, and the rough design of that type.
It is not out of the question that such a type could be checked into Whidbey if the forward-compatability issues could be sorted out. However, it is admittedly a very long shot. - Anonymous
June 12, 2004
The comment has been removed - Anonymous
June 20, 2004
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. - Anonymous
June 23, 2004
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. - Anonymous
June 28, 2004
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). - Anonymous
July 23, 2004
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.
i.e.
DateTime x = some-local-time (e.g. filetime)
DateTime y = x.ToLocalTime();
Assert.IsEqual(x,y);
DateTime z = x.ToUTC();
DateTime w = z.ToUTC();
Assert.IsEqual(w,z);
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.
i.e.
DateTime loc = filetime or something
UTCDateTime utc = loc.ToUTCDateTime();
DateTime x = loc.ToUTC();
Assert.IsTrue( utc == x );
DateTime y = x.ToLocal();
Assert.IsEqual(loc,y);
DateTime z = utc.ToLocal();
DateTime w = utc.ToTimeZone(curZone);
Assert.IsEqual(z,w);
Also +1 on the UnixTime functions mentioned above. Alternatively add a converter class to help simplify the transmogrification. - Anonymous
July 27, 2006
While doing my System.DateTime and System.TimeZone investigation, I come across some old discussions...