Bug #103144 | TIME column problems with getObject() and setObject() | ||
---|---|---|---|
Submitted: | 29 Mar 2021 13:15 | Modified: | 7 Apr 2021 10:12 |
Reporter: | Dario Menni | Email Updates: | |
Status: | Verified | Impact on me: | |
Category: | Connector / J | Severity: | S3 (Non-critical) |
Version: | 8.0.23 | OS: | Windows (10) |
Assigned to: | Assigned Account | CPU Architecture: | Any |
Tags: | connector, java |
[29 Mar 2021 13:15]
Dario Menni
[29 Mar 2021 13:28]
Dario Menni
I forgot to mention that if I store a LocalTime like this: LocalTime localTimeUTC = LocalTime.of(offsetDateTimeUTC.getHour(), offsetDateTimeUTC.getMinute()); Then on the database the time stored is the correct UTC time (13:25), however when retrieved it still shows the wrong offset (13:25+01:00)
[6 Apr 2021 6:22]
Alexander Soklakov
Hi Dario, What is your Connector/J version? For c/J 5.1 series you could try to set noTimezoneConversionForTimeType=true, though I'm not sure it will work in this case. The better solution would be to upgrade to c/J 8.0.23, we significantly reworked the date-time types support there. Please read https://insidemysql.com/support-for-date-time-types-in-connector-j-8-0/ about these changes.
[6 Apr 2021 7:09]
Dario Menni
You are right, I forgot to say the connector version, but I already am running version 8.0.23
[6 Apr 2021 11:35]
Alexander Soklakov
Connector/J 8.0.23 considers that OffsetTime is not an instant date-time class because the date part is absent there. Also the MySQL TIME type is also considered a non-instant. So no time zone preserving is attempted. OffsetTime value is converted to the local JVM time zone before sending to the server. When retrieved, it is constructed as LocalTime in a JVM time zone. But, additionally, there is a specific with conversion of the OffsetTime value to the local JVM time zone. Since the date part is absent, there is no way to decide how to apply DST rules. We could base on the current date, but in this case the same OffsetTime value will be stored differently over the year. Currently implemented solution uses the raw offset of the JVM time zone, like the time belongs to 1970-01-01 date without DST applied. It also rises questions, for example you get the +01:00 shift instead of +02:00 because of that. But at least OffsetTime values are consistent over the year. So, there is no universal solution about storing OffsetTime to MySQL at least until it does not support TIME_WITH_TIMEZONE SQL type. The question is what are the user expectation here. How do you expect an OffsetTime to be stored, according the current DST rules, or somehow else? The working solution for OffsetTime is to use varchar column and call preparedStatement.setObject(1, offsetTimeUTC, MysqlType.VARCHAR). In this case the string value formatted with DateTimeFormatter.ofPattern("HH:mm:ss.SSSSSSSSSXXX") is stored to db and when restored with resultSet.getObject("start_time", OffsetTime.class)) it's parsed back to the original OffsetTime value.
[6 Apr 2021 16:47]
Dario Menni
I'd expect OffsetTime to work in one of these 2 ways: 1) like OffsetDateTime, the time in OffsetTime is converted to the server's timezone time. 15:00+02:00 is stored as 13:00 2) The time in OffsetTime is stored as is completely ignoring the offset. 15:00+02:00 is stored as 15:00 Right now the stored time isn't converted to the server's time but is converted to my local time but ignores daylight savings. When retrieving an OffsetTime the time I receive is the exact value as in the database but with a +1 offset (ignores daylight savings). Whereas OffsetDateTime respects daylight savings Alternatively I'd open to completely give up on OffsetTime and use LocalTime, but I'd also need to receive confirmation that when storing LocalTime with setObject() and retrieving with getObject() the hours and minutes aren't converted at all but are kept exactly as they are
[7 Apr 2021 10:12]
Alexander Soklakov
LocalTime is never converted between time zones when stored to TIME or (VAR)CHAR columns. The only possible issue could be if you retrieve the TIMESTAMP value as LocalTime because of server-side implicit TIMESTAMP conversion to the session time zone, but that's a corner case. I leave this report as verified, we need to figure out the solution regarding OffsetTime <-> TIME conversion which better fits the user expectations. Thanks!