From 792c321a4f088df139787bc99ea0f05a5e9abdf3 Mon Sep 17 00:00:00 2001 From: Gord Thompson Date: Mon, 16 Jul 2018 10:32:28 -0600 Subject: [PATCH 1/6] fix for issue 744 --- .../sqlserver/jdbc/SQLServerResultSet.java | 10 ++++++ .../jdbc/resultset/ResultSetTest.java | 33 +++++++++++++++++++ 2 files changed, 43 insertions(+) diff --git a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerResultSet.java b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerResultSet.java index b017691bf..83f16f50a 100644 --- a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerResultSet.java +++ b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerResultSet.java @@ -2373,6 +2373,16 @@ public T getObject(int columnIndex, Class type) throws SQLException { returnValue = getTime(columnIndex); } else if (type == java.sql.Timestamp.class) { returnValue = getTimestamp(columnIndex); + } else if (type == java.time.LocalDateTime.class) { + returnValue = null; + java.sql.Timestamp ts = getTimestamp(columnIndex, + Calendar.getInstance(java.util.TimeZone.getTimeZone("UTC"))); + if (ts != null) { + var dtf = java.time.format.DateTimeFormatter + .ISO_LOCAL_DATE_TIME + .withZone(java.time.ZoneId.of("UTC")); + returnValue = java.time.LocalDateTime.parse(dtf.format(ts.toInstant())); + } } else if (type == microsoft.sql.DateTimeOffset.class) { returnValue = getDateTimeOffset(columnIndex); } else if (type == UUID.class) { diff --git a/src/test/java/com/microsoft/sqlserver/jdbc/resultset/ResultSetTest.java b/src/test/java/com/microsoft/sqlserver/jdbc/resultset/ResultSetTest.java index 8add5c13c..76f861815 100644 --- a/src/test/java/com/microsoft/sqlserver/jdbc/resultset/ResultSetTest.java +++ b/src/test/java/com/microsoft/sqlserver/jdbc/resultset/ResultSetTest.java @@ -21,6 +21,8 @@ import java.sql.SQLException; import java.sql.SQLXML; import java.sql.Statement; +import java.time.LocalDateTime; +import java.util.TimeZone; import java.util.UUID; import org.junit.jupiter.api.Test; @@ -240,6 +242,37 @@ public void testJdbc41ResultSetMethods() throws SQLException { } } + /** + * Tests getObject(n, java.time.LocalDateTime.class). + * + * @throws SQLException + */ + @Test + public void testGetLocalDateTime() throws SQLException { + try (Connection con = DriverManager.getConnection(connectionString); Statement stmt = con.createStatement()) { + TimeZone prevTimeZone = TimeZone.getDefault(); + TimeZone.setDefault(TimeZone.getTimeZone("America/Edmonton")); + + // a local date/time that does not actually exist because of Daylight Saving Time + final String testValue = "2018-03-11T02:00:00.1234567"; + + stmt.executeUpdate( + "CREATE TABLE " + tableName + " (id INT PRIMARY KEY, dt2 DATETIME2)"); + stmt.executeUpdate( + "INSERT INTO " + tableName + " (id, dt2) VALUES (1, '" + testValue + "')"); + + try (ResultSet rs = stmt.executeQuery("SELECT dt2 FROM " + tableName + " WHERE id=1")) { + rs.next(); + LocalDateTime actual = rs.getObject(1, LocalDateTime.class); + LocalDateTime expected = LocalDateTime.parse(testValue); + assertEquals(expected, actual); + } finally { + Utils.dropTableIfExists(tableName, stmt); + TimeZone.setDefault(prevTimeZone); + } + } + } + /** * Tests ResultSet#isWrapperFor and ResultSet#unwrap. * From d61dfe0065442a99fc505433af5e089d01262449 Mon Sep 17 00:00:00 2001 From: Gord Thompson Date: Mon, 16 Jul 2018 11:24:07 -0600 Subject: [PATCH 2/6] remove "var" declaration --- .../java/com/microsoft/sqlserver/jdbc/SQLServerResultSet.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerResultSet.java b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerResultSet.java index 83f16f50a..13d391c93 100644 --- a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerResultSet.java +++ b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerResultSet.java @@ -2378,7 +2378,7 @@ public T getObject(int columnIndex, Class type) throws SQLException { java.sql.Timestamp ts = getTimestamp(columnIndex, Calendar.getInstance(java.util.TimeZone.getTimeZone("UTC"))); if (ts != null) { - var dtf = java.time.format.DateTimeFormatter + java.time.format.DateTimeFormatter dtf = java.time.format.DateTimeFormatter .ISO_LOCAL_DATE_TIME .withZone(java.time.ZoneId.of("UTC")); returnValue = java.time.LocalDateTime.parse(dtf.format(ts.toInstant())); From d03ac25eca331894e5fa3699bc96f82b7b88d1b2 Mon Sep 17 00:00:00 2001 From: Gord Thompson Date: Mon, 16 Jul 2018 17:55:59 -0600 Subject: [PATCH 3/6] simple change to re-run CI checks after GitHub outage --- .../com/microsoft/sqlserver/jdbc/resultset/ResultSetTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/java/com/microsoft/sqlserver/jdbc/resultset/ResultSetTest.java b/src/test/java/com/microsoft/sqlserver/jdbc/resultset/ResultSetTest.java index 76f861815..0ec22ef7b 100644 --- a/src/test/java/com/microsoft/sqlserver/jdbc/resultset/ResultSetTest.java +++ b/src/test/java/com/microsoft/sqlserver/jdbc/resultset/ResultSetTest.java @@ -248,7 +248,7 @@ public void testJdbc41ResultSetMethods() throws SQLException { * @throws SQLException */ @Test - public void testGetLocalDateTime() throws SQLException { + public void testGetObjectAsLocalDateTime() throws SQLException { try (Connection con = DriverManager.getConnection(connectionString); Statement stmt = con.createStatement()) { TimeZone prevTimeZone = TimeZone.getDefault(); TimeZone.setDefault(TimeZone.getTimeZone("America/Edmonton")); From 7c3c9c0f7cadb8ff979a49d994bf44170c83c986 Mon Sep 17 00:00:00 2001 From: Gord Thompson Date: Tue, 17 Jul 2018 11:28:13 -0600 Subject: [PATCH 4/6] avoid conversion to/from string --- .../com/microsoft/sqlserver/jdbc/SQLServerResultSet.java | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerResultSet.java b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerResultSet.java index 13d391c93..0800e481c 100644 --- a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerResultSet.java +++ b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerResultSet.java @@ -2378,10 +2378,8 @@ public T getObject(int columnIndex, Class type) throws SQLException { java.sql.Timestamp ts = getTimestamp(columnIndex, Calendar.getInstance(java.util.TimeZone.getTimeZone("UTC"))); if (ts != null) { - java.time.format.DateTimeFormatter dtf = java.time.format.DateTimeFormatter - .ISO_LOCAL_DATE_TIME - .withZone(java.time.ZoneId.of("UTC")); - returnValue = java.time.LocalDateTime.parse(dtf.format(ts.toInstant())); + returnValue = java.time.LocalDateTime.ofInstant(ts.toInstant(), + java.time.ZoneId.of("UTC")); } } else if (type == microsoft.sql.DateTimeOffset.class) { returnValue = getDateTimeOffset(columnIndex); From e43f81208472bcc175ed31ca46ff459dd0c621c3 Mon Sep 17 00:00:00 2001 From: Gord Thompson Date: Wed, 18 Jul 2018 06:20:31 -0600 Subject: [PATCH 5/6] add support for LocalDate and LocalTime --- .../sqlserver/jdbc/SQLServerResultSet.java | 21 ++++++++++++---- .../jdbc/resultset/ResultSetTest.java | 25 ++++++++++++++----- 2 files changed, 35 insertions(+), 11 deletions(-) diff --git a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerResultSet.java b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerResultSet.java index 0800e481c..4abfd66b3 100644 --- a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerResultSet.java +++ b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerResultSet.java @@ -2373,13 +2373,24 @@ public T getObject(int columnIndex, Class type) throws SQLException { returnValue = getTime(columnIndex); } else if (type == java.sql.Timestamp.class) { returnValue = getTimestamp(columnIndex); - } else if (type == java.time.LocalDateTime.class) { - returnValue = null; + } else if (type == java.time.LocalDateTime.class + || type == java.time.LocalDate.class + || type == java.time.LocalTime.class) { java.sql.Timestamp ts = getTimestamp(columnIndex, Calendar.getInstance(java.util.TimeZone.getTimeZone("UTC"))); - if (ts != null) { - returnValue = java.time.LocalDateTime.ofInstant(ts.toInstant(), - java.time.ZoneId.of("UTC")); + if (ts == null) { + returnValue = null; + } else { + if (type == java.time.LocalDateTime.class) { + returnValue = java.time.LocalDateTime.ofInstant(ts.toInstant(), + java.time.ZoneId.of("UTC")); + } else if (type == java.time.LocalDate.class) { + returnValue = java.time.LocalDate.ofInstant(ts.toInstant(), + java.time.ZoneId.of("UTC")); + } else { + returnValue = java.time.LocalTime.ofInstant(ts.toInstant(), + java.time.ZoneId.of("UTC")); + } } } else if (type == microsoft.sql.DateTimeOffset.class) { returnValue = getDateTimeOffset(columnIndex); diff --git a/src/test/java/com/microsoft/sqlserver/jdbc/resultset/ResultSetTest.java b/src/test/java/com/microsoft/sqlserver/jdbc/resultset/ResultSetTest.java index 0ec22ef7b..eb73fd3ff 100644 --- a/src/test/java/com/microsoft/sqlserver/jdbc/resultset/ResultSetTest.java +++ b/src/test/java/com/microsoft/sqlserver/jdbc/resultset/ResultSetTest.java @@ -21,7 +21,9 @@ import java.sql.SQLException; import java.sql.SQLXML; import java.sql.Statement; +import java.time.LocalDate; import java.time.LocalDateTime; +import java.time.LocalTime; import java.util.TimeZone; import java.util.UUID; @@ -253,19 +255,30 @@ public void testGetObjectAsLocalDateTime() throws SQLException { TimeZone prevTimeZone = TimeZone.getDefault(); TimeZone.setDefault(TimeZone.getTimeZone("America/Edmonton")); - // a local date/time that does not actually exist because of Daylight Saving Time - final String testValue = "2018-03-11T02:00:00.1234567"; + // a local date/time that does not actually exist because of Daylight Saving Time + final String testValueDate = "2018-03-11"; + final String testValueTime = "02:00:00.1234567"; + final String testValueDateTime = testValueDate + "T" + testValueTime; stmt.executeUpdate( "CREATE TABLE " + tableName + " (id INT PRIMARY KEY, dt2 DATETIME2)"); stmt.executeUpdate( - "INSERT INTO " + tableName + " (id, dt2) VALUES (1, '" + testValue + "')"); + "INSERT INTO " + tableName + " (id, dt2) VALUES (1, '" + testValueDateTime + "')"); try (ResultSet rs = stmt.executeQuery("SELECT dt2 FROM " + tableName + " WHERE id=1")) { rs.next(); - LocalDateTime actual = rs.getObject(1, LocalDateTime.class); - LocalDateTime expected = LocalDateTime.parse(testValue); - assertEquals(expected, actual); + + LocalDateTime expectedLocalDateTime = LocalDateTime.parse(testValueDateTime); + LocalDateTime actualLocalDateTime = rs.getObject(1, LocalDateTime.class); + assertEquals(expectedLocalDateTime, actualLocalDateTime); + + LocalDate expectedLocalDate = LocalDate.parse(testValueDate); + LocalDate actualLocalDate = rs.getObject(1, LocalDate.class); + assertEquals(expectedLocalDate, actualLocalDate); + + LocalTime expectedLocalTime = LocalTime.parse(testValueTime); + LocalTime actualLocalTime = rs.getObject(1, LocalTime.class); + assertEquals(expectedLocalTime, actualLocalTime); } finally { Utils.dropTableIfExists(tableName, stmt); TimeZone.setDefault(prevTimeZone); From 1f30188d485913448b8b0f30304a259982a651dc Mon Sep 17 00:00:00 2001 From: Gord Thompson Date: Wed, 18 Jul 2018 10:27:25 -0600 Subject: [PATCH 6/6] LocalDate and LocalTime tweaks for Java 8 --- .../microsoft/sqlserver/jdbc/SQLServerResultSet.java | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerResultSet.java b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerResultSet.java index 4abfd66b3..acf6f71d6 100644 --- a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerResultSet.java +++ b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerResultSet.java @@ -2381,15 +2381,14 @@ public T getObject(int columnIndex, Class type) throws SQLException { if (ts == null) { returnValue = null; } else { + java.time.LocalDateTime ldt = java.time.LocalDateTime + .ofInstant(ts.toInstant(), java.time.ZoneId.of("UTC")); if (type == java.time.LocalDateTime.class) { - returnValue = java.time.LocalDateTime.ofInstant(ts.toInstant(), - java.time.ZoneId.of("UTC")); + returnValue = ldt; } else if (type == java.time.LocalDate.class) { - returnValue = java.time.LocalDate.ofInstant(ts.toInstant(), - java.time.ZoneId.of("UTC")); + returnValue = ldt.toLocalDate(); } else { - returnValue = java.time.LocalTime.ofInstant(ts.toInstant(), - java.time.ZoneId.of("UTC")); + returnValue = ldt.toLocalTime(); } } } else if (type == microsoft.sql.DateTimeOffset.class) {