我应如何最好地将java.util.Date
转换为Java 8的java.time.YearMonth
?
不幸的是,以下内容会抛出DateTimeException
异常:
YearMonth yearMonth = YearMonth.from(date.toInstant());
结果为:
java.time.DateTimeException: Unable to obtain YearMonth from TemporalAccessor: 2015-01-08T14:28:39.183Z of type java.time.Instant
at java.time.YearMonth.from(YearMonth.java:264)
...
我需要这个功能是因为我想使用JPA在数据库中存储年月
的值。目前JPA不支持年月
,所以我设计了以下YearMonthConverter
(省略导入):
// TODO (future): delete when next version of JPA (i.e. Java 9?) supports YearMonth. See https://java.net/jira/browse/JPA_SPEC-63
@Converter(autoApply = true)
public class YearMonthConverter implements AttributeConverter<YearMonth, Date> {
@Override
public Date convertToDatabaseColumn(YearMonth attribute) {
// uses default zone since in the end only dates are needed
return attribute == null ? null : Date.from(attribute.atDay(1).atStartOfDay(ZoneId.systemDefault()).toInstant());
}
@Override
public YearMonth convertToEntityAttribute(Date dbData) {
// TODO: check if Date -> YearMonth can't be done in a better way
if (dbData == null) return null;
Calendar calendar = Calendar.getInstance();
calendar.setTime(dbData);
return YearMonth.of(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH) + 1);
}
}
难道没有更好(更简洁,更短)的解决方案吗?(针对双向都适用的情况)
java.util.Date
,因为 a) 它不是java.sql.*
类型,b) 包含隐式时区(性能差且模糊使用系统时区),c) SQL 没有为年月定义这样的类型。更好的方法是使用 PROLEPTIC_MONTH 将YearMonth
映射到整数。 - Meno Hochschild