13
13
14
14
import java .lang .reflect .Field ;
15
15
import java .sql .BatchUpdateException ;
16
+ import java .sql .PreparedStatement ;
16
17
import java .sql .ResultSet ;
17
18
import java .sql .SQLException ;
18
19
import java .sql .Statement ;
20
+ import java .sql .Types ;
21
+ import java .text .SimpleDateFormat ;
22
+ import java .time .Instant ;
23
+ import java .util .Date ;
19
24
import java .util .Random ;
20
25
import java .util .UUID ;
21
26
import java .util .concurrent .CountDownLatch ;
31
36
import com .microsoft .sqlserver .jdbc .TestUtils ;
32
37
33
38
import org .junit .jupiter .api .AfterEach ;
39
+ import org .junit .jupiter .api .Assertions ;
34
40
import org .junit .jupiter .api .BeforeAll ;
35
41
import org .junit .jupiter .api .BeforeEach ;
36
42
import org .junit .jupiter .api .Tag ;
@@ -51,6 +57,7 @@ public class PreparedStatementTest extends AbstractTest {
51
57
final static String tableName2 = RandomUtil .getIdentifier ("tableTestStatementPoolingInternal2" );
52
58
final static String tableName3 = RandomUtil .getIdentifier ("tableTestPreparedStatementWithSpPrepare" );
53
59
final static String tableName4 = RandomUtil .getIdentifier ("tableTestPreparedStatementWithMultipleParams" );
60
+ final static String tableName5 = RandomUtil .getIdentifier ("tableTestPreparedStatementWithTimestamp" );
54
61
55
62
@ BeforeAll
56
63
public static void setupTests () throws Exception {
@@ -482,6 +489,43 @@ public void testPrepareRace() throws Exception {
482
489
}
483
490
}
484
491
492
+ @ Test
493
+ public void testTimestampStringTimeZoneFormat () throws SQLException {
494
+ String SELECT_SQL = "SELECT id, created_date, deleted_date FROM "
495
+ + AbstractSQLGenerator .escapeIdentifier (tableName5 ) + " WHERE id = ?" ;
496
+ String INSERT_SQL = "INSERT INTO " + AbstractSQLGenerator .escapeIdentifier (tableName5 )
497
+ + " (id, created_date, deleted_date) VALUES (?, ?, ?)" ;
498
+ String DATE_FORMAT_WITH_Z = "yyyy-MM-dd'T'HH:mm:ss'Z'" ;
499
+ SimpleDateFormat sdf = new SimpleDateFormat (DATE_FORMAT_WITH_Z );
500
+
501
+ try (SQLServerConnection con = (SQLServerConnection ) getConnection ()) {
502
+ executeSQL (con , "create table " + AbstractSQLGenerator .escapeIdentifier (tableName5 )
503
+ + "(id int, created_date datetime2, deleted_date datetime2)" );
504
+ }
505
+
506
+ try (PreparedStatement selectStatement = connection .prepareCall (SELECT_SQL );
507
+ PreparedStatement insertStatement = connection .prepareCall (INSERT_SQL );) {
508
+ Date createdDate = Date .from (Instant .parse ("2024-01-16T05:12:00Z" ));
509
+ Date deletedDate = Date .from (Instant .parse ("2024-01-16T06:34:00Z" ));
510
+ int id = 1 ;
511
+
512
+ insertStatement .setInt (1 , id );
513
+ insertStatement .setObject (2 , sdf .format (createdDate .getTime ()), Types .TIMESTAMP );
514
+ insertStatement .setObject (3 , sdf .format (deletedDate .getTime ()), Types .TIMESTAMP );
515
+
516
+ insertStatement .executeUpdate ();
517
+
518
+ selectStatement .setInt (1 , id );
519
+
520
+ try (ResultSet result = selectStatement .executeQuery ()) {
521
+ result .next ();
522
+ Assertions .assertEquals (id , result .getInt ("id" ));
523
+ Assertions .assertEquals (createdDate , new Date (result .getTimestamp ("created_date" ).getTime ()));
524
+ Assertions .assertEquals (deletedDate , new Date (result .getTimestamp ("deleted_date" ).getTime ()));
525
+ }
526
+ }
527
+ }
528
+
485
529
/**
486
530
* Test handling of the two configuration knobs related to prepared statement handling.
487
531
*
@@ -880,6 +924,7 @@ private static void dropTables() throws Exception {
880
924
TestUtils .dropTableIfExists (AbstractSQLGenerator .escapeIdentifier (tableName2 ), stmt );
881
925
TestUtils .dropTableIfExists (AbstractSQLGenerator .escapeIdentifier (tableName3 ), stmt );
882
926
TestUtils .dropTableIfExists (AbstractSQLGenerator .escapeIdentifier (tableName4 ), stmt );
927
+ TestUtils .dropTableIfExists (AbstractSQLGenerator .escapeIdentifier (tableName5 ), stmt );
883
928
}
884
929
}
885
930
0 commit comments