{"record":{"id":"2f3d47ded803ba12","repo":"chinabugotech/hutool","slug":"unsupported-type-from-map","errorCode":null,"errorMessage":"Unsupported type: [{}] from map: [{}]","messagePattern":"Unsupported type: \\[(.+?)\\] from map: \\[(.+?)\\]","errorType":"exception","errorClass":"ConvertException","httpStatus":null,"severity":"error","filePath":"hutool-core/src/main/java/cn/hutool/core/convert/impl/TemporalAccessorConverter.java","lineNumber":124,"sourceCode":"\t\t} else if (value instanceof TemporalAccessor) {\n\t\t\treturn parseFromTemporalAccessor((TemporalAccessor) value);\n\t\t} else if (value instanceof Date) {\n\t\t\tfinal DateTime dateTime = DateUtil.date((Date) value);\n\t\t\treturn parseFromInstant(dateTime.toInstant(), dateTime.getZoneId());\n\t\t} else if (value instanceof Calendar) {\n\t\t\tfinal Calendar calendar = (Calendar) value;\n\t\t\treturn parseFromInstant(calendar.toInstant(), calendar.getTimeZone().toZoneId());\n\t\t} else if (value instanceof Map) {\n\t\t\tfinal Map<?, ?> map = (Map<?, ?>) value;\n\t\t\tif (LocalDate.class.equals(this.targetType)) {\n\t\t\t\treturn LocalDate.of(Convert.toInt(map.get(\"year\")), Convert.toInt(map.get(\"month\")), Convert.toInt(map.get(\"day\")));\n\t\t\t} else if (LocalDateTime.class.equals(this.targetType)) {\n\t\t\t\treturn LocalDateTime.of(Convert.toInt(map.get(\"year\")), Convert.toInt(map.get(\"month\")), Convert.toInt(map.get(\"day\")),\n\t\t\t\t\tConvert.toInt(map.get(\"hour\")), Convert.toInt(map.get(\"minute\")), Convert.toInt(map.get(\"second\")), Convert.toInt(map.get(\"second\")));\n\t\t\t} else if (LocalTime.class.equals(this.targetType)) {\n\t\t\t\treturn LocalTime.of(Convert.toInt(map.get(\"hour\")), Convert.toInt(map.get(\"minute\")), Convert.toInt(map.get(\"second\")), Convert.toInt(map.get(\"nano\")));\n\t\t\t}\n\t\t\tthrow new ConvertException(\"Unsupported type: [{}] from map: [{}]\", this.targetType, map);\n\t\t} else {\n\t\t\treturn parseFromCharSequence(convertToStr(value));\n\t\t}\n\t}\n\n\t/**\n\t * 通过反射从字符串转java.time中的对象\n\t *\n\t * @param value 字符串值\n\t * @return 日期对象\n\t */\n\tprivate TemporalAccessor parseFromCharSequence(CharSequence value) {\n\t\tif (StrUtil.isBlank(value)) {\n\t\t\treturn null;\n\t\t}\n\n\t\tif (DayOfWeek.class.equals(this.targetType)) {\n\t\t\treturn DayOfWeek.valueOf(StrUtil.toString(value));","sourceCodeStart":106,"sourceCodeEnd":142,"githubUrl":"https://github.com/chinabugotech/hutool/blob/8870454b2a0c29cc6ffd31dcf5667c8ceb2fc442/hutool-core/src/main/java/cn/hutool/core/convert/impl/TemporalAccessorConverter.java#L106-L142","documentation":"Thrown by TemporalAccessorConverter.convertInternal() when the input value is a Map but the target java.time type is not LocalDate, LocalDateTime, or LocalTime. The Map branch only handles those three types; other temporal types like OffsetDateTime, ZonedDateTime, OffsetTime, Year, YearMonth, Instant, etc., are unsupported when the source is a Map.","triggerScenarios":"Convert.convert(OffsetDateTime.class, mapWithDateFields). Convert.convert(ZonedDateTime.class, jsonMap). Convert.convert(Year.class, map). Passing a Map to any temporal type not in {LocalDate, LocalDateTime, LocalTime}.","commonSituations":"Deserializing JSON maps into OffsetDateTime or ZonedDateTime fields of a DTO. Converting database row maps into temporal types beyond the three locals. ORM or JSON frameworks that produce Map<String,Object> and rely on Hutool for temporal conversion.","solutions":["Convert the Map to a String (ISO-8601 format) first, then convert the String to the temporal type: OffsetDateTime.parse(str).","Build the target temporal object manually from the Map entries instead of using the converter.","If the target is one of the supported three (LocalDate, LocalDateTime, LocalTime), ensure the Map keys are year/month/day/hour/minute/second/nano as expected.","Register a custom converter for the specific temporal type you need."],"exampleFix":"// before\nOffsetDateTime odt = Convert.convert(OffsetDateTime.class, dateMap); // throws\n\n// after\nLocalDateTime ldt = Convert.convert(LocalDateTime.class, dateMap);\nOffsetDateTime odt = ldt.atOffset(ZoneOffset.ofHours(8));","handlingStrategy":"validation","validationCode":"if (value instanceof Map &&\n    targetType != LocalDate.class && targetType != LocalDateTime.class\n    && targetType != LocalTime.class) {\n    // convert map to a string or build temporal manually\n    throw new IllegalArgumentException(\"Map source only supports LocalDate, LocalDateTime, LocalTime\");\n}","typeGuard":"static boolean supportsMapSource(Class<?> temporalType) {\n    return temporalType == LocalDate.class\n        || temporalType == LocalDateTime.class\n        || temporalType == LocalTime.class;\n}","tryCatchPattern":"try {\n    return Convert.convert(targetType, mapValue);\n} catch (ConvertException e) {\n    if (e.getMessage().contains(\"Unsupported type\") && value instanceof Map) {\n        // fallback: convert to string first, then parse\n        return Convert.convert(targetType, mapValue.toString());\n    }\n    throw e;\n}","preventionTips":["For temporal types beyond LocalDate/LocalDateTime/LocalTime, pass a String source instead of a Map.","Check supportsMapSource(targetType) before passing a Map to the temporal converter.","Register custom converters for temporal types you frequently need from Map sources."],"tags":["convert","temporal","java-time","map","convert-exception"],"backgroundTag":null,"analyzedSha":"8870454b2a0c29cc6ffd31dcf5667c8ceb2fc442","analyzedAt":"2026-08-14T04:01:12.892Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}