twitter
    Find out what I'm doing, Follow Me :)

DateTime & Daylight Saving SOAP Serialization Issue

We had a weird bug that seems like randomly occurred. After banging my head for few days, I found that it was related to DateTime serialization in .Net Framework. This application is an online application form that stored user's date of birth. Some of the users have their date of birth rollback one hour from the value that their originally entered e.g: if the user typed in 2 Feb 1962, it is saved in the system as 1 Feb 1962 11:00 PM.

The data is saved from the ASP.Net web application to the back office system through an Apache Axis Web Service.

We had few problems related to DateTime in the past. Among them are the fact that .Net DateTime is a value type. Hence, it is not nullable type, whereas SOAP Date type is nullable.

We used Apache Axis SOAP monitoring toolkit to monitor what is being sent across the wire. We found out inconsistencies in the date of birth value being sent. Some of them sent with GMT +10 time zone (GMT +10 being Melbourne), and some of them in GMT +11 (daylight saving time).

The problem is .Net Datetime does not store time zone information in the object. And this timezone information is required for the SOAP serialization to work. The only way that .Net can serialized the datetime value is to calculate the timezone information from the setting on the machine. So when the user entered 2 Feb 1962 as his/her date of birth. The datetime object value is 2 Feb 1962 00:00:00 without any timezone information. So before .Net sent the value across through SOAP, it will append the calculated local timezone setting. In this case, .Net thinks that 2 Feb 1962 is within daylight saving period. Hence it is sent as "1962-02-02T00:00:00.0000000+11:00". Which is wrong, because there were no daylight saving in that year in Melbourne timezone (GMT +10). In fact there were no daylight saving in Australia from 1944-1967 (refer here).

Apparently, .Net using some kind of algorithm to determine the daylight saving in the past. It fails to acknowledge that there were political and social events that cancels or changes the normal daylight saving time such as Sydney Olympics or Commonwealth Games in Melbourne. In contrast, Java recognizes that there are no definitive ways to know whether a particular date falls within daylight saving period. Java respect the timezone database which can be retrieved from ftp://elsie.nci.nih.gov/pub/. In this case, Java thinks it is "1962-02-01T23:00:00.000Z" which shifts it an hour earlier. Hence the a day shift in the Date of Birth.

Lessons learned:
  • there is no such things as random bugs. It only means you haven't found the real cause yet.
  • avoid using java.util.Date or .Net DateTime class in webservice for Java & .Net integration. Create a wrapper around these framework classes.
  • programmers should know history :))

0 comments: