Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

JDK8 实体类有 LocalDate 类型的字段时报错:NoSuchMethodError: java.time.LocalDate.ofInstant(Ljava/time/Instant;Ljava/time/ZoneId;) #43

Closed
troyzhxu opened this issue May 10, 2022 · 1 comment
Labels

Comments

@troyzhxu
Copy link
Owner

troyzhxu commented May 10, 2022

解决方法:

方法一:

使用 java.sql.Date 类型替代 LocalDate

方法二:

添加一个自定义的转换器,继承 DateFieldConvertor ,注册为 Spring 的 Bean:

@Bean
public DateFieldConvertor dateFieldConvertor() {
    return new DateFieldConvertor() {

        @Override
        public Object convert(Class<?> targetType, Object value) {
            Class<?> valueType = value.getClass();
            if (Date.class.isAssignableFrom(valueType)) {
                Date date = (Date) value;
                if (targetType == java.sql.Date.class) {
                    return new java.sql.Date(date.getTime());
                }
                if (targetType == Timestamp.class) {
                    return new Timestamp(date.getTime());
                }
                if (targetType == LocalDateTime.class) {
                    // 注意:java.sql.Date 的 toInstant() 方法会抛异常
                    if (date instanceof java.sql.Date) {
                        LocalDate localDate = ((java.sql.Date) date).toLocalDate();
                        return LocalDateTime.of(localDate, LocalTime.of(0, 0, 0, 0));
                    }
                    return LocalDateTime.ofInstant(date.toInstant(), getZoneId());
                }
                if (targetType == LocalDate.class) {
                    // 注意:java.sql.Date 的 toInstant() 方法会抛异常
                    if (date instanceof java.sql.Date) {
                        return ((java.sql.Date) date).toLocalDate();
                    }
                    return toLocalDate(date.toInstant());
                }
                if (targetType == Date.class) {
                    return date;
                }
            }
            LocalDateTime dateTime;
            if (valueType == LocalDateTime.class) {
                dateTime = (LocalDateTime) value;
            } else {
                dateTime = LocalDateTime.of((LocalDate) value, LocalTime.of(0, 0));
            }
            if (targetType == LocalDateTime.class) {
                return dateTime;
            }
            Instant instant = dateTime.atZone(getZoneId()).toInstant();
            if (targetType == Date.class) {
                return new Date(instant.toEpochMilli());
            }
            if (targetType == java.sql.Date.class) {
                return new java.sql.Date(instant.toEpochMilli());
            }
            if (targetType == Timestamp.class) {
                return new Timestamp(instant.toEpochMilli());
            }
            if (targetType == LocalDate.class) {
                return toLocalDate(instant);
            }
            throw new UnsupportedOperationException();
        }

        private LocalDate toLocalDate(Instant instant) {
            ZoneOffset offset = getZoneId().getRules().getOffset(instant);
            long localSecond = instant.getEpochSecond() + offset.getTotalSeconds();
            long localEpochDay = Math.floorDiv(localSecond, 86400);
            return LocalDate.ofEpochDay(localEpochDay);
        }

    };
}
@troyzhxu troyzhxu added the bug label May 10, 2022
@troyzhxu troyzhxu changed the title DateFieldConvertor 用到了 JDK9 才用的 LocalDate.ofInstant(Instant) 方法,不兼容 JDK8 DateFieldConvertor 用到了 JDK9 才有的 LocalDate.ofInstant(Instant) 方法,不兼容 JDK8 May 10, 2022
@troyzhxu troyzhxu changed the title DateFieldConvertor 用到了 JDK9 才有的 LocalDate.ofInstant(Instant) 方法,不兼容 JDK8 当实体类使用 LocalDate 类型的字段时:NoSuchMethodError: java.time.LocalDate.ofInstant(Ljava/time/Instant;Ljava/time/ZoneId;)Ljava/time/LocalDate; May 10, 2022
@troyzhxu troyzhxu changed the title 当实体类使用 LocalDate 类型的字段时:NoSuchMethodError: java.time.LocalDate.ofInstant(Ljava/time/Instant;Ljava/time/ZoneId;)Ljava/time/LocalDate; 实体类有 LocalDate 类型的字段时报错:NoSuchMethodError: java.time.LocalDate.ofInstant(Ljava/time/Instant;Ljava/time/ZoneId;) May 10, 2022
@troyzhxu troyzhxu changed the title 实体类有 LocalDate 类型的字段时报错:NoSuchMethodError: java.time.LocalDate.ofInstant(Ljava/time/Instant;Ljava/time/ZoneId;) JDK8 实体类有 LocalDate 类型的字段时报错:NoSuchMethodError: java.time.LocalDate.ofInstant(Ljava/time/Instant;Ljava/time/ZoneId;) May 10, 2022
@troyzhxu
Copy link
Owner Author

troyzhxu commented May 11, 2022

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant