{"record":{"id":"fc67d0c8cc65dfe6","repo":"apache/seatunnel","slug":"unable-to-convert-to-localdate-from-a-java-sql-tim","errorCode":null,"errorMessage":"Unable to convert to LocalDate from a java.sql.Time value '","messagePattern":"Unable to convert to LocalDate from a java\\.sql\\.Time value '","errorType":"exception","errorClass":"java.lang.IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"seatunnel-connectors-v2/connector-cdc/connector-cdc-base/src/main/java/org/apache/seatunnel/connectors/cdc/debezium/utils/TemporalConversions.java","lineNumber":71,"sourceCode":"\n    private TemporalConversions() {}\n\n    @SuppressWarnings(\"MagicNumber\")\n    public static LocalDate toLocalDate(Object obj) {\n        if (obj == null) {\n            return null;\n        }\n        if (obj instanceof LocalDate) {\n            return (LocalDate) obj;\n        }\n        if (obj instanceof LocalDateTime) {\n            return ((LocalDateTime) obj).toLocalDate();\n        }\n        if (obj instanceof java.sql.Date) {\n            return ((java.sql.Date) obj).toLocalDate();\n        }\n        if (obj instanceof java.sql.Time) {\n            throw new IllegalArgumentException(\n                    \"Unable to convert to LocalDate from a java.sql.Time value '\" + obj + \"'\");\n        }\n        if (obj instanceof java.util.Date) {\n            java.util.Date date = (java.util.Date) obj;\n            return LocalDate.of(date.getYear() + 1900, date.getMonth() + 1, date.getDate());\n        }\n        if (obj instanceof Long) {\n            if ((Long) obj > ChronoField.EPOCH_DAY.range().getMaximum()) {\n                return Instant.ofEpochMilli((Long) obj)\n                        .atZone(ZoneId.systemDefault())\n                        .toLocalDate();\n            }\n            // Assume the value is the epoch day number\n            return LocalDate.ofEpochDay((Long) obj);\n        }\n        if (obj instanceof Integer) {\n            // Assume the value is the epoch day number\n            return LocalDate.ofEpochDay((Integer) obj);","sourceCodeStart":53,"sourceCodeEnd":89,"githubUrl":"https://github.com/apache/seatunnel/blob/cf67b549a7a6c35fa0beb12d83c62892427ea919/seatunnel-connectors-v2/connector-cdc/connector-cdc-base/src/main/java/org/apache/seatunnel/connectors/cdc/debezium/utils/TemporalConversions.java#L53-L89","documentation":"TemporalConversions.toLocalDate(Object) converts supported temporal objects (LocalDate, LocalDateTime, java.sql.Date, java.util.Date, Number epoch) to LocalDate. A java.sql.Time explicitly throws IllegalArgumentException, because a time-of-day cannot be a calendar date. This guards against schema/value mismatches where a TIME value is fed to a DATE field.","triggerScenarios":"Calling TemporalConversions.toLocalDate() with a java.sql.Time argument, typically when a source column's actual JDBC type is TIME but the declared SeaTunnel type is DATE.","commonSituations":"Schema/type drift: the catalog declares DATE while the CDC value deserialized as TIME; copy connectors mapping a TIME column into a DATE field.","solutions":["Align the declared column type with the actual data: declare TIME for the column, or select the intended DATE column.","Convert at source: change the query to cast Time to a Date (e.g. CAST(col AS DATE) or CURDATE-based expression).","Pre-check the object type and route Time values through a toLocalTime() path instead of toLocalDate()."],"exampleFix":"// before\nLocalDate d = TemporalConversions.toLocalDate(sqlTimeObj); // throws\n// after\nif (obj instanceof java.sql.Time) {\n    LocalTime t = ((java.sql.Time) obj).toLocalTime();\n    // handle as time, not date\n} else {\n    LocalDate d = TemporalConversions.toLocalDate(obj);\n}","handlingStrategy":"type-guard","validationCode":"// Java\nstatic boolean isConvertibleToDate(Object o) {\n    return o instanceof LocalDate || o instanceof LocalDateTime || o instanceof java.sql.Date\n        || o instanceof java.util.Date || o instanceof Number;\n}","typeGuard":"if (obj instanceof java.sql.Time) {\n    throw new IllegalArgumentException(\"expected a DATE value, got TIME \" + obj);\n}\nLocalDate d = TemporalConversions.toLocalDate(obj);","tryCatchPattern":"try {\n    date = TemporalConversions.toLocalDate(value);\n} catch (IllegalArgumentException e) {\n    log.warn(\"TIME value fed to DATE field: {}\", value);\n    date = ((java.sql.Time) value).toLocalTime().atDate(LocalDate.EPOCH); // or route to toLocalTime()\n}","preventionTips":["Verify that declared SeaTunnel column types match the actual JDBC types of the source columns","Never map TIME columns to DATE fields in connector schemas","Add a type check before calling TemporalConversions converters when the input type is dynamic"],"tags":["cdc","datetime","type-mismatch","conversion"],"backgroundTag":"type-mismatch","analyzedSha":"cf67b549a7a6c35fa0beb12d83c62892427ea919","analyzedAt":"2026-09-10T21:44:55.265Z","contentChangedAt":"2026-09-10T21:44:55.265Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}