Hi
Attached patch fixes bug #599 (JtdsPreparedStatement setTimestamp DST Bug) in jTDS 1.3. The patch was tested and created at revision 1250. Below are some details about the fix:
Root Cause:
As described in the bug report in Support.timeFromZone method setting a 'wall' time that does not exist in the local timezone (due to daylight saving) into a local calendar causes the calendar to shift the hour-of-day field. And also the DateTime class was extracting the date and time components using the local timezone instead of using the user specified timezone (in the calendar parameter of setTimestamp method of the PreparedStatement).
Fix:
DateTime class constructors have been updated to accept a TimeZone parameter and extract the date and time components from the given Timestamp/Date/Time in that timezone. A null TimeZone means the date and time components are to be extracted in the default timezone. Constructor changes are for fixing the storage part (i.e. setter methods of the PreparedStatement). To fix the retrieval part (i.e. getter methods of the ResultSet) additional static converter methods (e.g. toTimestamp(Timestamp, Timezone)) which take a timezone to interpret the stored date and time components in for creating either a Timestamp/Date/Time have been added.
DateTime class felt like a good place to put the core change as it was already doing the extraction/conversions based on the default timezone and doing them for an arbitrary timezone was just an extension of it. This fix reduces creation of one calendar object during storage, whereas for retrieval no additional calendars are created than before.
I found that setter methods for Timestamp/Date/Time of the PreparedStatement and getter methods for Timestamp/Date/Time of the ResultSet were the only places where a Calendar (i.e. timezone) could be passed. So, apart from the implementation of those methods all other invocations of JtdsPreparedStatement.setParameter and Support.convert pass a null for the timezone parameter.
Tests:
Additional tests for the bug and the changes have been added. I haven't been able to get all the tests to pass on my system (6 errors and 12 failures). But no additional tests fail because of this fix. Attached is also a log of test failures. My system configuration is: Windows 7 Professional 64-bit, Intel Core i7-2600 CPU @ 3.40 GHz, 8 GB RAM, Oracle JDK 1.7.0_10. The tests were run against SQL Server 2008 R2 Express edition, as system admin user against a default database instance. I also had to comment out ResultSetTest.testPessimisticConcurrency as that test hanged on my system.
We can discuss the changes made as comments here or in the forum. Any suggestions for additional improvements or changes are welcome.
Regards
Shailender
Anonymous
Attached test failure log.