Menu

#438 Timestamp conversion for instants during daylight saving time is off

v2.5.*
closed-fixed
None
2.7.3
5
2021-10-30
2021-03-30
No

TimestampDataType's timezone offset handling compensates for java.sql.Timestamp.valueOf() always handling times as if in local time by adjusting the resulting time by the current timezone's offset. However, it uses Timezone.getRawOffset() that returns the offset to standard time. If the timestamp is for an instant during daylight saving time, the result will be off by the difference between daylight saving time and standard time. The offset should be calculated with Timezone.getOffset() instead.

See also issues [#304] and [#380].

:::udiff
diff --git a/dbunit/src/main/java/org/dbunit/dataset/datatype/TimestampDataType.java b/dbunit/src/main/java/org/dbunit/dataset/datatype/TimestampDataType.java
index 2d9ba556..ef038643 100644
--- a/dbunit/src/main/java/org/dbunit/dataset/datatype/TimestampDataType.java
+++ b/dbunit/src/main/java/org/dbunit/dataset/datatype/TimestampDataType.java
@@ -143,7 +143,7 @@ public class TimestampDataType extends AbstractDataType
             if (zoneValue != null)
             {
                 TimeZone localTZ = java.util.TimeZone.getDefault();

-                BigInteger localTZOffset = BigInteger.valueOf(localTZ.getRawOffset());
+                BigInteger localTZOffset = BigInteger.valueOf(localTZ.getOffset(ts.getTime()));
                 BigInteger time = BigInteger.valueOf(ts.getTime() / 1000 * 1000).add(localTZOffset)
                         .multiply(ONE_BILLION).add(BigInteger.valueOf(ts.getNanos()));
                 int hours = Integer.parseInt(zoneValue.substring(1, 3));
diff --git a/dbunit/src/test/java/org/dbunit/dataset/datatype/TimestampDataTypeTest.java b/dbunit/src/test/java/org/dbunit/dataset/datatype/TimestampDataTypeTest.java
index 699f4eb8..3920c23e 100644
--- a/dbunit/src/test/java/org/dbunit/dataset/datatype/TimestampDataTypeTest.java
+++ b/dbunit/src/test/java/org/dbunit/dataset/datatype/TimestampDataTypeTest.java
@@ -132,6 +132,20 @@ public class TimestampDataTypeTest extends AbstractDataTypeTest
         assertEquals(ts1, THIS_TYPE.typeCast(ts2));
     }


+    public void testWithTimezone_DaylightSavingTime() throws Exception
+    {
+        Timestamp ts1 = makeTimestamp(2021, 5, 26, 18, 42, 50, 900, "Europe/Helsinki");
+        String ts2 = "2021-06-26 18:42:50.900 +0300";
+        assertEquals(ts1, THIS_TYPE.typeCast(ts2));
+    }
+
+    public void testWithTimezone_StandardTime() throws TypeCastException
+    {
+        Timestamp ts1 = makeTimestamp(2021, 1, 14, 18, 42, 50, 900, "Europe/Helsinki");
+        String ts2 = "2021-02-14 18:42:50.900 +0200";
+        assertEquals(ts1, THIS_TYPE.typeCast(ts2));
+    }
+
     @Override
     public void testTypeCast() throws Exception
     {

Related

Bugs: #304
Bugs: #380

Discussion

  • Jarmo Jaakkola

    Jarmo Jaakkola - 2021-03-30

    Oops, there's a code completion failure in the diff. Obviously it should be Exception, not TypeCastException in the standar time test case.

     
  • Jeff Jensen

    Jeff Jensen - 2021-10-30
    • status: open --> closed-fixed
    • assigned_to: Jeff Jensen
    • Fixed Release: (not fixed) --> 2.7.3
     
  • Jeff Jensen

    Jeff Jensen - 2021-10-30

    Thank you for the report and especially the fix w/tests.

     

Log in to post a comment.

MongoDB Logo MongoDB