Thursday, 22 November 2007

Java-WCF DateTime Interop

Here's the scenario:

We have a WCF IIS-hosted service with one of the parameters on the OperationContract being a standard DateTime parameter. The parameter logically represents a date with no time component e.g. DOB. When we write a WCF client that sends data to the service, the date argument is correctly serialized and sent across the wire to the service, no problems at all.

The problem emerges when writing a Java client. We generate the client proxy code by pointing IntelliJ at the WSDL, which then grinds out all the proxy code. OK so far. We start to write our client code to invoke the proxy and we notice, hey, our date parameter has been reflected out to be a 'Calendar' object. OK quick check of the javadocs tells us this shouldn't be a problem. So we write some code to get a date from the user:
SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
sdf.parse("11/12/2000");
locator.getdefaultEp().invokeWsMethod(sdf.getCalendar());

Hmmm, a little bit more verbose than the equivalent C# code, but doesn't look like there's anything wrong with that. Lets send it off and see what happens...

Looking at the svclog file however tells us that the date parameter has been serialized to UTC:
<dateofbirth type="xsd:dateTime">2000-12-10T11:00:00.000Z</dateofbirth>
It appears that the default behaviour of the Java serialiser (JAXB in this case I believe) is that it converts the Calendar's value from the local machine's timezone into UTC, in this case (NZST) taking 13 hours off the passed in time. In order to get around this you must set the timezone to UTC before parsing the date string:
SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
sdf.parse("11/12/2000");
locator.getdefaultEp().invokeWsMethod(sdf.getCalendar());

This will ensure the time is serialised and transmitted exactly as you want it. Not exactly rocket science once you understand the APIs however can be tricky to get there without know what's going on under the covers.

Some interesting background reading on Java and .Net date handling can be found at the MSDN article Coding Best Practices Using DateTime in the .NET Framework and the Sun Web Service Interop Tutorial