1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 package org.dbunit.dataset.datatype;
22
23 import static org.assertj.core.api.Assertions.assertThat;
24 import static org.junit.jupiter.api.Assumptions.assumeTrue;
25
26 import java.sql.Connection;
27 import java.sql.PreparedStatement;
28 import java.sql.ResultSet;
29 import java.sql.SQLException;
30 import java.sql.Statement;
31 import java.sql.Timestamp;
32 import java.sql.Types;
33 import java.time.OffsetDateTime;
34
35 import org.dbunit.AbstractDatabaseIT;
36 import org.dbunit.DatabaseEnvironment;
37 import org.dbunit.TestFeature;
38 import org.dbunit.database.IDatabaseConnection;
39 import org.junit.jupiter.api.AfterEach;
40 import org.junit.jupiter.api.BeforeEach;
41 import org.junit.jupiter.api.Test;
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66 class TimestampDataTypeIT
67 {
68 private static final String ZONED_TABLE = "TIMESTAMPTYPE_TZ_IT";
69
70 private static final String PLAIN_TABLE = "TIMESTAMPTYPE_PLAIN_IT";
71
72 private static final String DATASET_VALUE = "2026-07-22 15:00:00 -0200";
73
74 private IDatabaseConnection connection;
75
76 @BeforeEach
77 void setUp() throws Exception
78 {
79 connection = DatabaseEnvironment.getInstance().getConnection();
80 }
81
82 @AfterEach
83 void tearDown() throws Exception
84 {
85 if (connection != null)
86 {
87 dropTableQuietly(ZONED_TABLE);
88 dropTableQuietly(PLAIN_TABLE);
89 connection.close();
90 connection = null;
91 }
92 }
93
94 private void dropTableQuietly(final String tableName)
95 {
96 try (Statement statement = connection.getConnection().createStatement())
97 {
98 statement.execute("DROP TABLE " + tableName);
99 } catch (final SQLException e)
100 {
101
102
103
104 }
105 }
106
107 @Test
108 void testSetSqlValue_withOffsetDifferentFromLocalZone_writesCorrectInstantToTimestampWithTimeZoneColumn()
109 throws Exception
110 {
111 assumeTrue(AbstractDatabaseIT.environmentHasFeature(TestFeature.TIMESTAMP_WITH_TIMEZONE),
112 "Skipping: active database profile declares TIMESTAMP_WITH_TIMEZONE unsupported "
113 + "(see dbunit.profile.unsupportedFeatures).");
114
115 final Connection jdbcConnection = connection.getConnection();
116 dropTableQuietly(ZONED_TABLE);
117 try (Statement statement = jdbcConnection.createStatement())
118 {
119 statement.execute("CREATE TABLE " + ZONED_TABLE
120 + " (ID INTEGER NOT NULL PRIMARY KEY, TIM TIMESTAMP WITH TIME ZONE)");
121 }
122
123 try (PreparedStatement insert = jdbcConnection
124 .prepareStatement("INSERT INTO " + ZONED_TABLE + " VALUES (1, ?)"))
125 {
126 final int parameterType = insert.getParameterMetaData().getParameterType(1);
127 assumeTrue(parameterType == Types.TIMESTAMP_WITH_TIMEZONE,
128 "Skipping: active database driver does not report TIMESTAMP_WITH_TIMEZONE "
129 + "parameter metadata for this column.");
130
131 new TimestampDataType().setSqlValue(DATASET_VALUE, 1, insert);
132 insert.executeUpdate();
133 }
134
135 try (PreparedStatement select = jdbcConnection
136 .prepareStatement("SELECT TIM FROM " + ZONED_TABLE + " WHERE ID = 1");
137 ResultSet resultSet = select.executeQuery())
138 {
139 resultSet.next();
140 final OffsetDateTime stored = resultSet.getObject(1, OffsetDateTime.class);
141 assertThat(stored)
142 .as("a TIMESTAMP WITH TIME ZONE column must store the offset implied by "
143 + "the dataset's own time zone, not the JVM's default time zone.")
144 .isEqualTo(OffsetDateTime.parse("2026-07-22T15:00:00-02:00"));
145 }
146 }
147
148 @Test
149 void testSetSqlValue_withOffsetDifferentFromLocalZone_writesLiteralDigitsToTimestampColumnWithoutTimeZone()
150 throws Exception
151 {
152 final Connection jdbcConnection = connection.getConnection();
153 dropTableQuietly(PLAIN_TABLE);
154 final boolean isSqlServer = jdbcConnection.getMetaData().getDatabaseProductName()
155 .startsWith("Microsoft SQL Server");
156 final String plainTimestampType = isSqlServer ? "DATETIME2" : "TIMESTAMP";
157 try (Statement statement = jdbcConnection.createStatement())
158 {
159 statement.execute("CREATE TABLE " + PLAIN_TABLE
160 + " (ID INTEGER NOT NULL PRIMARY KEY, TIM " + plainTimestampType + ")");
161 }
162
163 try (PreparedStatement insert = jdbcConnection
164 .prepareStatement("INSERT INTO " + PLAIN_TABLE + " VALUES (1, ?)"))
165 {
166 new TimestampDataType().setSqlValue(DATASET_VALUE, 1, insert);
167 insert.executeUpdate();
168 }
169
170 try (PreparedStatement select = jdbcConnection
171 .prepareStatement("SELECT TIM FROM " + PLAIN_TABLE + " WHERE ID = 1");
172 ResultSet resultSet = select.executeQuery())
173 {
174 resultSet.next();
175 assertThat(resultSet.getTimestamp(1))
176 .as("issue #711: a column without a time zone must still receive the "
177 + "dataset's literal wall-clock digits, regardless of the JVM's "
178 + "default time zone.")
179 .isEqualTo(Timestamp.valueOf("2026-07-22 15:00:00"));
180 }
181 }
182 }