| Bug #82005 | JdbcDateValueFactory fails to parse some dates | ||
|---|---|---|---|
| Submitted: | 26 Jun 2016 9:09 | Modified: | 9 Mar 2017 15:17 |
| Reporter: | Alexandru-Constantin Bledea | Email Updates: | |
| Status: | Closed | Impact on me: | |
| Category: | Connector / J | Severity: | S1 (Critical) |
| Version: | 6.0.3 | OS: | Ubuntu |
| Assigned to: | CPU Architecture: | Any | |
[26 Jun 2016 9:12]
Alexandru-Constantin Bledea
The plain java version is actually
Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("Europe/Bucharest"), Locale.US);
cal.set(MILLISECOND, 0);
cal.setLenient(false);
cal.getTimeInMillis();
cal.set(1994, MARCH, 27, 0, 0, 0);
long ms = cal.getTimeInMillis();
I don't know how to edit the initial submission
[27 Jun 2016 12:06]
Chiranjeevi Battula
Hello Alexandru-Constantin Bledea, Thank you for the bug report and test case. Verified as described. Thanks, Chiranjeevi.
[27 Jun 2016 12:11]
Chiranjeevi Battula
Exception in thread "main" java.lang.IllegalArgumentException: HOUR_OF_DAY: 0 -> 1 at java.util.GregorianCalendar.computeTime(GregorianCalendar.java:2829) at java.util.Calendar.updateTime(Calendar.java:3393) at java.util.Calendar.getTimeInMillis(Calendar.java:1782) at com.mysql.cj.jdbc.io.JdbcDateValueFactory.createFromDate(JdbcDateValueFactory.java:66) at javaapplication3.bug_82005.main(bug_82005.java:32) C:\Users\cbattula\AppData\Local\NetBeans\Cache\8.1\executor-snippets\run.xml:53: Java returned: 1 BUILD FAILED (total time: 0 seconds)
[28 Sep 2016 7:48]
Alexandru-Constantin Bledea
SimpleDateFormat can handle this date even if is set as not lenient
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd", US);
sdf.setTimeZone(TimeZone.getTimeZone("Europe/Bucharest"));
sdf.setLenient(false);
System.out.println(sdf.parse("1994-03-27"));
[31 Jan 2017 12:02]
Alexander Rumyantsev
It also can be reproduced in 6.0.5 version.
[9 Mar 2017 15:17]
Daniel So
Posted by developer: Added the following entry to the Connector/J 6.0.6 changelog: "An IllegalArgumentException was thrown when lenient was false for a Calendar object and the hours, minutes, and seconds explicitly set via the Calendar constructor did not match the values resulted from the timezone conversion of the Calendar object's date value."
[26 Feb 2019 19:06]
Eduardo Simioni
I know this issue has been closed, but this comment might save time for some people. The problem in my case was occurring given the following scenario: - A column with type DATE in a table, with value '2018-11-04'. - DB Server on AWS/RDS with timezone UTC - JDBC connection URL with parameter: serverTimezone=America/Sao_Paulo - Connector/J version 8.0.15 - JVM OpenJDK Runtime Environment (build 1.8.0_191-b12) running in a Linux server with timezone America/Sao_Paulo It happens that '2018-11-04 00:00:00' was the start of summer time for the mentioned time zone, which actually makes '2018-11-04 00:00:00' not exist, since it changes to '2018-11-04 01:00:00'. Note that the column type is DATE, so, there is no time information, but it is mapped to a Calendar in my model. When MySQL was trying to convert, it was throwing an exception: Caused by: java.lang.IllegalArgumentException: HOUR_OF_DAY: 0 -> 1 at java.util.GregorianCalendar.computeTime(GregorianCalendar.java:2829) at java.util.Calendar.updateTime(Calendar.java:3393) at java.util.Calendar.getTimeInMillis(Calendar.java:1782) at com.mysql.cj.result.SqlTimestampValueFactory.createFromTimestamp(SqlTimestampValueFactory.java:100) The workaround that seems to work best is: - Remove serverTimezone from JDBC connection URL - Add hibernate.jdbc.time_zone configuration set to America/Sao_Paulo
[30 May 2019 18:46]
Joel SalmeroĢn Viver
Also for information to others: We also ran into the America/Sao_Paulo invalid timezone dates due to an error by our sysadmins of not patching the the os in time; hence we received this error running a Debezium kafka connector which uses jdbc to read the bin_log api. We had to update the invalid timestamp rows to add an hour (those timestamps from 2018-11-04 00:00 to 2018-11-04 0:59), and then also the version of the java jdk (8u101) the kconnect workers were using; upgrading (to 8u172 - tzdata2018c REF: https://www.oracle.com/technetwork/cn/java/javase/downloads/tzdata-versions-138805.html
[12 May 2020 10:34]
Surj Basan
Firstly, I just wanted to thank the previous commenters for pointing out the timezone issues. Secondly, this is how I resolved my own issue with this bug: simply by adding "default_time_zone = UTC" to local my.conf. The server already had it, but my local one didn't. Apparently, this made MySQL encounter impossible dates and it threw the exception logged in this ticket.

Description: The 6.x drivers don't work when parsing some dates The column definition is simply "date NOT NULL" I can select where the date = '1994-03-27' and i get columns, however, when it comes to them getting mapped, the driver fails The stacktrace is Caused by: java.lang.IllegalArgumentException: HOUR_OF_DAY: 0 -> 1 at java.util.GregorianCalendar.computeTime(GregorianCalendar.java:2829) at java.util.Calendar.updateTime(Calendar.java:3393) at java.util.Calendar.getTimeInMillis(Calendar.java:1782) at com.mysql.cj.jdbc.io.JdbcDateValueFactory.createFromDate(JdbcDateValueFactory.java:66) at com.mysql.cj.jdbc.io.JdbcDateValueFactory.createFromDate(JdbcDateValueFactory.java:39) at com.mysql.cj.core.io.BaseDecoratingValueFactory.createFromDate(BaseDecoratingValueFactory.java:46) at com.mysql.cj.core.io.BaseDecoratingValueFactory.createFromDate(BaseDecoratingValueFactory.java:46) at com.mysql.cj.core.io.MysqlTextValueDecoder.decodeDate(MysqlTextValueDecoder.java:67) at com.mysql.cj.jdbc.ResultSetRow.decodeAndCreateReturnValue(ResultSetRow.java:113) at com.mysql.cj.jdbc.ResultSetRow.getValueFromBytes(ResultSetRow.java:269) at com.mysql.cj.jdbc.ByteArrayRow.getValue(ByteArrayRow.java:89) at com.mysql.cj.jdbc.ResultSetImpl.getNonStringValueFromRow(ResultSetImpl.java:813) at com.mysql.cj.jdbc.ResultSetImpl.getDateOrTimestampValueFromRow(ResultSetImpl.java:826) at com.mysql.cj.jdbc.ResultSetImpl.getDate(ResultSetImpl.java:971) at com.mysql.cj.jdbc.ResultSetImpl.getDate(ResultSetImpl.java:982) at org.hibernate.type.descriptor.sql.DateTypeDescriptor$2.doExtract(DateTypeDescriptor.java:74) at org.hibernate.type.descriptor.sql.BasicExtractor.extract(BasicExtractor.java:64) at org.hibernate.type.AbstractStandardBasicType.nullSafeGet(AbstractStandardBasicType.java:267) at org.hibernate.type.AbstractStandardBasicType.nullSafeGet(AbstractStandardBasicType.java:263) at org.hibernate.type.AbstractStandardBasicType.nullSafeGet(AbstractStandardBasicType.java:253) at org.hibernate.type.AbstractStandardBasicType.hydrate(AbstractStandardBasicType.java:338) at org.hibernate.persister.entity.AbstractEntityPersister.hydrate(AbstractEntityPersister.java:2969) at org.hibernate.loader.Loader.loadFromResultSet(Loader.java:1696) at org.hibernate.loader.Loader.instanceNotYetLoaded(Loader.java:1628) at org.hibernate.loader.Loader.getRow(Loader.java:1515) at org.hibernate.loader.Loader.getRowFromResultSet(Loader.java:726) at org.hibernate.loader.Loader.processResultSet(Loader.java:953) at org.hibernate.loader.Loader.doQuery(Loader.java:921) at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:355) at org.hibernate.loader.Loader.doList(Loader.java:2554) at org.hibernate.loader.Loader.doList(Loader.java:2540) at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2370) at org.hibernate.loader.Loader.list(Loader.java:2365) at org.hibernate.loader.hql.QueryLoader.list(QueryLoader.java:497) at org.hibernate.hql.internal.ast.QueryTranslatorImpl.list(QueryTranslatorImpl.java:387) at org.hibernate.engine.query.spi.HQLQueryPlan.performList(HQLQueryPlan.java:236) at org.hibernate.internal.SessionImpl.list(SessionImpl.java:1300) at org.hibernate.internal.QueryImpl.list(QueryImpl.java:103) at org.hibernate.jpa.internal.QueryImpl.list(QueryImpl.java:573) at org.hibernate.jpa.internal.QueryImpl.getResultList(QueryImpl.java:449) at org.hibernate.jpa.criteria.compile.CriteriaQueryTypeQueryAdapter.getResultList(CriteriaQueryTypeQueryAdapter.java:67) at org.springframework.data.jpa.repository.support.SimpleJpaRepository.findAll(SimpleJpaRepository.java:323) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) How to repeat: using mysql classes: public static void main(String[] args) { new JdbcDateValueFactory(TimeZone.getTimeZone("Europe/Bucharest")).createFromDate(1994, 3, 27); } plain java: public static void main(String[] args) { Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("Europe/Bucharest"), Locale.US); cal.set(MILLISECOND, 0); cal.set(0, 0, 0, 0, 0); cal.setLenient(false); // hmmm... cal.set(1994, MARCH, 27); long ms = cal.getTimeInMillis(); // boom! } Suggested fix: leaving the calendar as lenient