Description:
mysql-server version 8.0.32, server timeZone: PDT
mysql-connector version: 8.0.32
jdbcurl configed : serverTimezone=America/Tijuana
details:
1: we have two datebase node , A and B , there has data sync from A to B.
2. A-timezone: CST , B: America/Tijuana
3. do query from B Exception "java.lang.IllegalArgumentException: HOUR_OF_DAY: 2 -> 3 " happened.
Caused by: com.mysql.cj.exceptions.WrongArgumentException: HOUR_OF_DAY: 2 -> 3
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) ~[na:1.8.0_172]
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) ~[na:1.8.0_172]
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) ~[na:1.8.0_172]
at java.lang.reflect.Constructor.newInstance(Constructor.java:423) ~[na:1.8.0_172]
at com.mysql.cj.exceptions.ExceptionFactory.createException(ExceptionFactory.java:61) ~[mysql-connector-j-8.0.32.jar:8.0.32]
at com.mysql.cj.exceptions.ExceptionFactory.createException(ExceptionFactory.java:105) ~[mysql-connector-j-8.0.32.jar:8.0.32]
at com.mysql.cj.result.SqlTimestampValueFactory.localCreateFromDatetime(SqlTimestampValueFactory.java:195) ~[mysql-connector-j-8.0.32.jar:8.0.32]
at com.mysql.cj.result.SqlTimestampValueFactory.localCreateFromDatetime(SqlTimestampValueFactory.java:51) ~[mysql-connector-j-8.0.32.jar:8.0.32]
at com.mysql.cj.result.AbstractDateTimeValueFactory.createFromDatetime(AbstractDateTimeValueFactory.java:104) ~[mysql-connector-j-8.0.32.jar:8.0.32]
at com.mysql.cj.protocol.a.MysqlTextValueDecoder.decodeDatetime(MysqlTextValueDecoder.java:90) ~[mysql-connector-j-8.0.32.jar:8.0.32]
at com.mysql.cj.protocol.result.AbstractResultsetRow.decodeAndCreateReturnValue(AbstractResultsetRow.java:86) ~[mysql-connector-j-8.0.32.jar:8.0.32]
at com.mysql.cj.protocol.result.AbstractResultsetRow.getValueFromBytes(AbstractResultsetRow.java:243) ~[mysql-connector-j-8.0.32.jar:8.0.32]
at com.mysql.cj.protocol.a.result.TextBufferRow.getValue(TextBufferRow.java:132) ~[mysql-connector-j-8.0.32.jar:8.0.32]
... 107 common frames omitted
Caused by: java.lang.IllegalArgumentException: HOUR_OF_DAY: 2 -> 3
at java.util.GregorianCalendar.computeTime(GregorianCalendar.java:2829) ~[na:1.8.0_172]
at java.util.Calendar.updateTime(Calendar.java:3393) ~[na:1.8.0_172]
at java.util.Calendar.getTimeInMillis(Calendar.java:1782) ~[na:1.8.0_172]
at com.mysql.cj.result.SqlTimestampValueFactory.localCreateFromDatetime(SqlTimestampValueFactory.java:191) ~[mysql-connector-j-8.0.32.jar:8.0.32]
... 113 common frames omitted
How to repeat:
i found some db record with time "2023-03-12 02:45:45" in db B query exception can occur.
datetime :2023-03-12 02:45:45 set in DB A and sync to DB B, but db B timeZone is pdt timezone. at this time pst need to convert to PDT.
in com.mysql.cj.result.SqlTimestampValueFactory#localCreateFromDatetime
Calendar set Lenient to false. and actually the value of Lenient default to true.
Suggested fix:
synchronized (this.defaultTimeZone) {
Calendar c;
if (this.cal != null) {
c = this.cal;
} else {
// c.f. Bug#11540 for details on locale
c = Calendar.getInstance(this.pset.getBooleanProperty(PropertyKey.preserveInstants).getValue() ? this.connectionTimeZone : this.defaultTimeZone,
Locale.US);
c.setLenient(false); // delete this value settting.