Wednesday, September 29, 2004
On a recent project, I came across an interesting issue with assigning the current date and time to a promoted property in a Message Assignment shape.
The problem highlighted itself in our Audit database where we were auditing process state changes. The submission date of each audited record appeared to be 1 hour ahead than the current local time (based on GMT with Daylight Savings Time in effect - meaning we are currently +1 to UTC).
Our scenario involves writing an audit record from the web site that is initiating the process, then each subsequent audit is performed at various steps within a BizTalk orchestration. Each audit record contains some meta data extracted from the envelope, plus the XML fragment of the header within the envelope and optionally the body from within the envelope.
The first audit record is written by the web site. It uses a class created by xsd.exe which is based on the envelope schema deployed in BizTalk (not a BizTalk Envelope schema though). The code populates the class, then uses the XmlSerialization class to serialise the object into XML.
Each subsequent audit within the BizTalk orchestration effectively creates a new message (based on the envelope schema), updates the messageId, processStatus and submissionDate promoted properties within a Message Assignment shape, and then calls the Audit Web Service passing the message (as a string - long story, but that's the way it currently is) as an argument.
The first audit record has the correct time in the Oracle database, but every subsequent audit record has a time that is 1 hour ahead!
In the web site I'm using the expression DateTime.Now to populate the current date/time in the submissionDate property of my object. When serialised by .NET using XmlSerialization, it converts this date into a Sortable Date Time pattern (identified as 's' in .NET) as defined by ISO 8601. In addition, the DateTime.Now value is in local time, and it takes this into account when building the ISO 8601 date string. For example:
From this date value you can clearly see that the date/time is in UTC format with a +01:00 for the adjustment for daylight savings time. So, this is a correct date/time for British Summertime.
When I set the submissionDate promoted property in BizTalk using the expression DateTime.Now, it should output the same or similar value, taking into account that DateTime.Now returns a local time, and that the date string should encode the daylight savings offset. However, it doesn't...
The following is a date string output from BizTalk. Bearing in mind that the message is serialised into XML and then passed to the Audit Web Service. This is what is received by the web service:
The date/time string format is based on the Universal Sortable Date Time pattern (identified by 'u' in .NET) and is the correct local time but does not have any daylight savings adjustment associated with it! This means that when the Audit Web Service converts the string into a DateTime object using either System.Convert.ToString() or DateTime.Parse(), it takes the daylight savings adjustment into account and adds 1 hour!. It didn't work with DateTime.ParseExact( dateTimeString, "u", System.Globalization.DateTimeInfo.InvariantInfo ) either.
So, in order to fix this, we had to use the DateTime.UtcNow in the orchestration whenever we set the submission date promoted property so that the DateTime.Parse method could take into account current regional settings when converting the string to a DateTime.