-
Notifications
You must be signed in to change notification settings - Fork 913
Description
Describe the issue
Retrieving a TIME value of '24:00' via ResultSet#getObject(int, LocalTime.class) results in a java.time.DateTimeException, when the value is transmitted in binary:
Invalid value for NanoOfDay (valid values 0 - 86399999999999): 86400000000000
java.time.DateTimeException: Invalid value for NanoOfDay (valid values 0 - 86399999999999): 86400000000000
at java.base/java.time.temporal.ValueRange.checkValidValue(ValueRange.java:319)
at java.base/java.time.temporal.ChronoField.checkValidValue(ChronoField.java:718)
at java.base/java.time.LocalTime.ofNanoOfDay(LocalTime.java:400)
at org.postgresql.jdbc.TimestampUtils.toLocalTimeBin(TimestampUtils.java:1440)
Driver Version?
42.7.3
Java Version?
OpenJDK 64-Bit Server VM Temurin-17.0.9+9 (build 17.0.9+9, mixed mode)
OS Version?
Debian 12
PostgreSQL Version?
PostgreSQL 15.6 (Debian 15.6-1.pgdg120+2) on x86_64-pc-linux-gnu, compiled by gcc (Debian 12.2.0-14) 12.2.0, 64-bit
To Reproduce
Steps to reproduce the behaviour:
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.Properties;
public class TestLocalDateMax {
public static void main(String []args) throws Exception {
// it may be necessary to specify `?prepareThreshold=-1` in the URL to force binary transfer
String url = "jdbc:postgresql://localhost:5432/test";
Properties props = new Properties();
props.setProperty("user", "test");
props.setProperty("password", "test");
try ( Connection conn = DriverManager.getConnection(url, props) ){
try ( Statement statement = conn.createStatement() ) {
try (ResultSet rs = statement.executeQuery( "SELECT TIME '24:00'") ){
if (rs.next())
System.out.println( "Get String: " + rs.getObject(1, LocalTime.class));
}
}
}
}
}Expected behaviour
TIME '24:00' should convert to LocalTime.MAX - as it does, when the value is transferred in text-mode
Side note
TIMETZ (time with time zone) values of 24:00 (regardless of the specified offset) also suffer from the same issue (ResultSet#getObject(int, OffsetTime.class)). But the existing/working conversion of text-values seems to be a whole'nother can of worms (if the text-value starts-with 24:00:00, the server-sent offset is discarded and OffsetTime.MAX (offset -18:00) is used.