DateTime, Serialization and TimeZones


A reader asks:


 


We have an issue with the DateTime data type using serialization across timezones. All works well where we are interested in both the date and time. However, when the Date portion is of interest only, for example Birthday, (not many people know the exact time nor do they generally care), so the time portion will be 00:00:00 as initialised. As this is serialized and sent over a timezone this date could be changed to be the previous day, with a time of 23:00:00. If this user then logged into the system in the other time zone they would now see their birthday as being a day earlier and they would complain it was incorrect; rightly so. In our opinion this is not correct, the date should not change when time is irrelevant. As a suggestion it would be good if there was a property on the DateTime to mark it is Date only. This would result in an exception if the time portion was maintained, and the serialization would not change the value over time zones.


 


I gathered some comments from the product team on this that I thought were thoughtful and generally interesting so I am posting them here.


 


This is an issue I have seen a few times before.


For V1.0 and V1.1, There is a work-around for XML Serialization. You can indicate in the schema that the DateTime is a Date only.  If you start from schema, you should use xsd:date primitive type, to change the object model you can use custom attribute on the member:


 


    [XmlElementAttribute(DataType=”date”)]


    public DateTime date;


 


or


 


    [XmlAttributeAttribute(DataType=”date”)]


    public DateTime date;


 


Notice that this will not work for DataSet or SOAP Serializer.


 


Another work around is to call ToLocalTime() on the DateTime before serializing and ToUniversalTime() after serializing. This is sort of cheating because it is not really a UTC date, but it should make the time zone adjustment go away.


 


In a future release we do have planned a solution that is similar but not identical to what you have requested. You can mark a DateTime instance as Local, UTC or Unspecified, and Unspecified means that it should not be serialized with a time zone. Unfortunately it won’t magically take effect because it would break compatibility. But there will be ways to opt-in to this behavior for DataSet, XML Serialization and XML Convert.

Comments (21)

  1. Brat Adams answered a question about DateTime, Serialization and TimeZones For me it seems that .NET 2.0 will have another thing that was ‘invented’ a long time ago, a date only datatype.

  2. Interested says:

    >In a future release we do have planned a solution that is similar

    By future release you mean Whidbey?

  3. Ray Jezek says:

    Yes, it has always baffeled me as well why there are not Date and Time datatypes in .NET. There tons of times when only one or the other is relevant. That would be a good addition for 2.0.

  4. Brad Abrams says:

    Well, I don’t like to commit to things I don’t have direct control over, but our goal is to get it in the next major release of the .NET Framework which is Whidbey…

  5. Brad,

    Speaking of Date/Time issues. I work in an area where at times that the display of dates should maintain its original format. (for example, records with German Dates should display with German spellings even on other systems)

    I had asked about this, it seems that the framework uses the system date time structure which isn’t very cultureally aware.

    I have a couple of requests, which may not happen until LH timeframe which is fine.

    One a date/time stucture that will allow for dates back to BC time frame.

    A structure that can allow for cultural overide. (if the local culture on the machine is US for example and a Document has a german date it can overide the culture and display the date literally but still be sortable.

    Ok I lied, a few more items that would be nice. (an api to allow for introductions of more calanders (I personally have to deal with the Julian calandar, Gregorian. Hebrew, French revolutionary, (some records I deal with are still Julian as recently as 1912 (Russian documents)

    I can personally feel the pain of the lack of a date type or a time type seperate from each other. Especially in documents that Time may not matter although some things do matter from the point of view that all things appear in Local time for the documents I deal with. Birth, death, Deed etc etc. Transistion of calandars from Julian to Gregorian.

    in some areas.

    Although we have had some interesting debates in recording certain historical events.

    The space shuttle accident in Jan 1986 as a different occurance based on time zone for example.

    Oh well. hoping that windows becomes more DATE:TIME culturally aware in the LH time frame. (perhaps it can show up before then.

  6. Jeremy Gray says:

    (posted to both Dare’s blog and Brad’s blog)

    To be clear – fixes in this area are needed WELL in advance of Whidbey.

    This need cannot be overstated, as there are pre-Whidbey applications that simply cannot rely on DateTime’s various local-time-related ambiguities, due to issues with savings time fallback, etc. nor can those applications wait until Whidbey in order to be released.

    Such applications must work with UTC DateTimes, but even that doesn’t entirely work because the Framework still considers those times to be local, re-exposing the application to the same set of ambiguities. Once XmlConvert is added into the equation the problem is again multiplied, causing any internal standardization on UTC DateTimes to be wrecked by XmlConvert’s behaviour.

    We’re not exactly in "missing feature" territory here: this is well off into "critical short-sightedness" territory and as such should be considered a bug.

    If a change to this behaviour causes breaking changes, it will only break applications that are themselves aleady broken – coded on top of an outstanding known issue. Why do I consider these apps (including mine) to already be broken? Because there is presently _no_ way to use DateTime without exposing one’s self to these ambiguities.

    I frankly can’t believe that fixes to these issues aren’t occurring earlier than the Whidbey timeframe. Since there are definitely numerous .NET applications that ship DateTimes across time zones and/or have to keep running across savings time fallback windows, I can only assume that none of these applications are considered mission-critical enough to justify fixing these bugs. 🙁

  7. SpiderMan says:

    I got this problem since FX 1.0. And I think its better to have a Time type in FX.

  8. I am a colleague of Brad’s and I’m the development owner of DateTime. I wanted to respond to the feedback on this thread, particularly the excellent feedback from Douglas Husemann and Jeremy Gray.

    Serialization in XML is the Number 1 complaint associated with the DateTime. It is definitely something we are committed to fixing in Whidbey.

    There may be a misunderstanding, but there is no current plan to introduce a new "Date" data type to the System namespace. It is important to keep the number of distinct data types in the System namespace small because so much code needs to special-case it. The DateTime class was designed to meet the scenarios associated with a Date, a Time and a combined Date and Time. There are cases in the rest of the framework where some formatting options effectively preclude the usage as a stand-alone Date which we will be correcting in Whidbey. The use of the "zzz" format by XML Serialization, XML Convert, and DataSet is the most extreme example of this because this format is only valid in cases where the time is significant and the time is Local. It precludes Date-only and UTC scenarios. If we could wind the clock back to before shipping V1.0 we would have left the "zzz" format off when serializing DateTime.

    Regarding the request for a servicing release. Introducing new functionality into our V1.0 and V1.1 releases is always significantly more risky and expensive than a regular release. Feedback such as you are providing here is very useful in convincing people that the extra cost and risk is justified. In fact the more specific business impact and adoption impact about this issue from as many distinct sources as I can get is useful in trying to get all the right teams and individuals bought in that this work should be done. If you know others impacted by this, or you can provide more information about its impact on you, that would be helpful in making something happen. Please contact me (amoore@microsoft.com) if there is more feedback you can provide. My personal opinion is that I agree with you and we should do something for V1.1 at the least.

    Regarding compatibility: the only circumstances when I see customers significantly more inflamed than you are right now about this is not when we have bugs in our product, but when fixing bugs causes reasonably functioning code to break. And compatibility issues often go directly to impacting your users and customers as they upgrade their operating systems or runtimes, or even when they install service packs. Unfortunately it is easy to take a dependency on the weird way DateTime serializes in XML, so we have to be very careful about how we introduce fixes in Whidbey, and we have to be even more careful about anything we consider in servicing, which has an even higher compatibility bar.

    Requests for a "historical" DateTime have been very infrequent. We are unlikely to provide such a thing in the Longhorn timeframe due to lack of demand. There may be a good 3rd party opportunity for a library for historical dating that interoperates well with the DateTime class.

    I will pass on the request for more calendars to the team that owns that area.

    I am not clear about your request for a more culturally aware DateTime. This FAQ may be of help in finding ways to do this with the current framework:

    http://www.gotdotnet.com/team/clr/bcl/TechArticles/techarticles/DateTimeFAQ/FAQ.aspx

  9. Brandon Paddock says:

    I’ve recently encountered problems with managing Dates using DateTime in a project I’m currently working on. As was the case with the original poster, my program is storing a BirthDate for customer records. My problem is this..

    -I need to maintain a BirthDate entry in the SQL database for each customer entry in the table.

    -I need to retrieve that BirthDate and put it in a DataSet for use in my app.

    -I need my app to calculate the customer’s (in this case, a patient – actually) age. The database has an entry for an Age value, however most of the patient data was imported from another system which did not include a seperate Age value. So my program calculates an Age from the BirthDate and current Date, and then saves the Age to the database. In this way, the Age entry should always be up-to-date.

    …My app’s function is to spawn an InfoPath process (from a jscript) and fill in the selected patient’s ID number. The InfoPath form then fills in that patient’s demographic data from the database. The app does this, submits the form to a SharePoint library, and then closes immediately.

    So..

    -The BirthDate value must be properly imported into the InfoPath form.

    -It must then be in a format such that when it is promoted to a SharePoint Library column, the Library Views can properly display the BirthDate and sort by it if asked to.

    My current solution involves storing the BirthDate as a String most of the time. It is converted to a DateTime for Age calculation only. If it is not in the proper format (for instance, some of the imported data includes a birthdate of 00/00/0000), the user is asked to correct it.

    This isn’t an ideal solution but seems to be working for now.

    I also have a second problem involving the transfer of Exam Dates and Times to the InfoPath form (these values are NOT stored in the database). I’ve gotten it to work for now by using the following "tricks":

    -The Exam Date and Time are entered in the client app, not the IP Form as originally planned. They’re then sent to the Form by way of the jscript call.

    -A Date Picker is used in the client app, but the result is parsed to a String with the time information removed before being sent to the Form.

    -The Time is entered into a text box with some validation logic, and is also transmitted as a String.

    This was necessary because of a w weird case in InfoPath (even with SP1) where it refuses to store a Date entered into it in such a way that the SharePoint Library could properly filter it when the Primary Data Source was an SQL DB and the Date was being stored locally in the form (on a non-SQL form I *think* I didn’t have this problem). No matter what I tried it would always send the value to the SP Library as a "MM-DD-YYYY" format, and SharePoint’s [Today] Filter Value used "MM/DD/YYYY". Thus, the filters did not work.

    So my point is… My life would be much easier if a consistent Date dataype and format existed across .NET, SQL, InfoPath/XML, and SharePoint/ASP.NET. And I think my program could potentiall be more robust if it could actually store useful dates in a format other than String.

  10. Be careful when implementing this:

    "Another work around is to call ToLocalTime() on the DateTime before serializing and ToUniversalTime() after serializing. This is sort of cheating because it is not really a UTC date, but it should make the time zone adjustment go away."

    and working with a DataSet. You will be modifying datarows that may not need to be marked as modified on both trips. Carefully check your RowState and handle accordingly.

  11. Date Without Time When Serializing