diff --git a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerResultSet.java b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerResultSet.java index 612c44ab3..bf4f0c1bd 100644 --- a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerResultSet.java +++ b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerResultSet.java @@ -2398,6 +2398,20 @@ public T getObject(int columnIndex, Class type) throws SQLException { returnValue = ldt.toLocalTime(); } } + } else if (type == java.time.OffsetDateTime.class) { + microsoft.sql.DateTimeOffset dateTimeOffset = getDateTimeOffset(columnIndex); + if (dateTimeOffset == null) { + returnValue = null; + } else { + returnValue = dateTimeOffset.getOffsetDateTime(); + } + } else if (type == java.time.OffsetTime.class) { + microsoft.sql.DateTimeOffset dateTimeOffset = getDateTimeOffset(columnIndex); + if (dateTimeOffset == null) { + returnValue = null; + } else { + returnValue = dateTimeOffset.getOffsetDateTime().toOffsetTime(); + } } else if (type == microsoft.sql.DateTimeOffset.class) { returnValue = getDateTimeOffset(columnIndex); } else if (type == UUID.class) { diff --git a/src/main/java/microsoft/sql/DateTimeOffset.java b/src/main/java/microsoft/sql/DateTimeOffset.java index fc5135b43..170ddce42 100644 --- a/src/main/java/microsoft/sql/DateTimeOffset.java +++ b/src/main/java/microsoft/sql/DateTimeOffset.java @@ -215,6 +215,18 @@ public java.sql.Timestamp getTimestamp() { return timestamp; } + /** + * Returns OffsetDateTime equivalent to this DateTimeOffset object. + * + * @return OffsetDateTime equivalent to this DateTimeOffset object. + */ + public java.time.OffsetDateTime getOffsetDateTime() { + java.time.ZoneOffset zoneOffset = java.time.ZoneOffset.ofTotalSeconds(60 * minutesOffset); + java.time.LocalDateTime localDateTime = java.time.LocalDateTime.ofEpochSecond(utcMillis / 1000, nanos, + zoneOffset); + return java.time.OffsetDateTime.of(localDateTime, zoneOffset); + } + /** * Returns this DateTimeOffset object's offset value. * 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 574a928df..a76da0d7c 100644 --- a/src/test/java/com/microsoft/sqlserver/jdbc/resultset/ResultSetTest.java +++ b/src/test/java/com/microsoft/sqlserver/jdbc/resultset/ResultSetTest.java @@ -24,6 +24,8 @@ import java.time.LocalDate; import java.time.LocalDateTime; import java.time.LocalTime; +import java.time.OffsetDateTime; +import java.time.OffsetTime; import java.util.TimeZone; import java.util.UUID; @@ -291,6 +293,40 @@ public void testGetObjectAsLocalDateTime() throws SQLException { } } + /** + * Tests getObject(n, java.time.OffsetDateTime.class) and getObject(n, java.time.OffsetTime.class). + * + * @throws SQLException + */ + @Test + public void testGetObjectAsOffsetDateTime() throws SQLException { + try (Connection con = DriverManager.getConnection(connectionString); Statement stmt = con.createStatement()) { + final String testValue = "2018-01-02T11:22:33.123456700+12:34"; + + stmt.executeUpdate("CREATE TABLE " + AbstractSQLGenerator.escapeIdentifier(tableName) + + " (id INT PRIMARY KEY, dto DATETIMEOFFSET, dto2 DATETIMEOFFSET)"); + stmt.executeUpdate("INSERT INTO " + AbstractSQLGenerator.escapeIdentifier(tableName) + + " (id, dto, dto2) VALUES (1, '" + testValue + "', null)"); + + try (ResultSet rs = stmt.executeQuery( + "SELECT dto, dto2 FROM " + AbstractSQLGenerator.escapeIdentifier(tableName) + " WHERE id=1")) { + rs.next(); + + OffsetDateTime expected = OffsetDateTime.parse(testValue); + OffsetDateTime actual = rs.getObject(1, OffsetDateTime.class); + assertEquals(expected, actual); + assertNull(rs.getObject(2, OffsetDateTime.class)); + + OffsetTime expectedTime = OffsetTime.parse(testValue.split("T")[1]); + OffsetTime actualTime = rs.getObject(1, OffsetTime.class); + assertEquals(expectedTime, actualTime); + assertNull(rs.getObject(2, OffsetTime.class)); + } finally { + TestUtils.dropTableIfExists(AbstractSQLGenerator.escapeIdentifier(tableName), stmt); + } + } + } + /** * Tests ResultSet#isWrapperFor and ResultSet#unwrap. *