Java ResultSet getDate()返回的日期不正确且正确
我正在从假日表创建LocalDate的列表。数据库表中的日期都是正确的,但是当我使用ResultSet getDate()方法并用所有日期填充列表时,其中4个日期是错误的,6个是正确的。我正在寻找任何帮助,找出为什么会出现这种情况Java ResultSet getDate()返回的日期不正确且正确,java,mysql,jdbc,resultset,Java,Mysql,Jdbc,Resultset,我正在从假日表创建LocalDate的列表。数据库表中的日期都是正确的,但是当我使用ResultSet getDate()方法并用所有日期填充列表时,其中4个日期是错误的,6个是正确的。我正在寻找任何帮助,找出为什么会出现这种情况 final LocalDate currentDay = LocalDate.now(); final List<LocalDate> holidays = getHolidays(currentDay); //This method takes in
final LocalDate currentDay = LocalDate.now();
final List<LocalDate> holidays = getHolidays(currentDay);
//This method takes in a date and calculates the holidays that occur that year
public static List<LocalDate> getHolidays(final LocalDate date) {
final List<LocalDate> holidayList = new ArrayList<LocalDate>();
try {
final PreparedStatement holidaysByYearQuery = conn.prepareStatement(
"SELECT fulldate FROM holidays WHERE YEAR(fulldate) = ?");
holidaysByYearQuery.setObject(1, date.getYear());
final ResultSet holidaysByYearResult = holidaysByYearQuery.executeQuery();
while (holidaysByYearResult.next()) {
final Date holidate = (Date) holidaysByYearResult.getObject(1);
final LocalDate holiday = holidate.toLocalDate();
holidayList.add(holiday);
}
} catch (final SQLException e) {
LOGGER.log(Level.WARNING, "Could not query holiday table: " + e.getMessage());
}
return holidayList;
}
// This is the query used in Java:
com.mysql.cj.jdbc.PreparedStatement@1c27c773: SELECT fulldate FROM holidays WHERE YEAR(fulldate) = 2019
// Here is the list that is returned from the method
[2018-12-31, 2019-02-17, 2019-04-19, 2019-05-20, 2019-07-01, 2019-08-05, 2019-09-02, 2019-10-14, 2019-12-24, 2019-12-25]
如您所见,列表两端的两个日期不正确。我假设getDate()方法发生了一些问题。有人能解释一下吗?干杯。你为什么把糟糕的传统类
Date
和现代LocalDate
混为一谈?你为什么要选(日期)
SQL标准DATE
如果列的类型类似于SQL标准DATE
,请将LocalDate
与符合JDBC 4.2或更高版本的JDBC驱动程序一起使用
LocalDate ld = myResultSet.getObject( … , LocalDate.class ) ;
SQL标准带时区的时间戳
如果列的类型类似于SQL标准带时区的时间戳,则必须考虑时区以确定日期
OffsetDateTime odt = myResultSet.getObject( … , OffsetDateTime.class ) ;
ZoneId z = ZoneId.of( "Australia/Sydney" ) ;
ZonedDateTime zdt = odt.atZoneSameInstant( z ) ;
LocalDate ld = zdt.toLocalDate() ;
SQL标准不带时区的时间戳
如果列的数据类型类似于SQL标准TIMESTAMP而不带时区
,例如MySQL类型DATETIME
,请使用Java类型LocalDateTime
。此类型只有日期和时间,没有时区上下文或UTC偏移。所以这种类型并不代表一个时刻
LocalDateTime ldt = myResultSet.getObject( … , OffsetDateTime.class ) ;
LocalDate ld = ldt.toLocalDate() ;
您的列的数据类型到底是什么?您使用的是什么数据库系统?如果只存储日期,为什么要使用DateTime作为类型?ResultSet有一个getDate方法。我猜这是关于时区和不同的夏令时changes@BasilBourqueDATETIME和Mysql(Innodb)@JoakimDanielson它只是我现在拥有的模式。我以前使用过DATE,但它有完全相同的问题。您对仅日期值使用了错误的类型。将列定义为
DATE
。强制转换是解决方案的旧尝试,因为resultSet.getDate()不返回LocalDate。使用myResultSet.getObject(…,LocalDate.class);作品日期和本地日期的混合是导致这几个日期被抵消的原因吗?同时,我也非常感谢您提供关于有时区和无时区的信息。这似乎是一个更为稳健的解决方案。@RWri-东部标准时间(EST)生效的日期的Date
值不正确。EDT于2019-03-10开始,将于2019-11-03结束。JDBC的默认行为是将java.sql.Date
与JVM的默认时区关联,除非指定了其他时区。显然,元旦的日期/时间值返回为2018-12-31 23:00:00 EST
,并被截断为2018-12-31
@GordThompson。你知道为什么只有4/10的日期是不正确的吗。如果它是由时区引起的,我希望所有的日期都被抵消。@RWri re:“如果它是由时区引起的,我希望所有的日期都被抵消。”-不一定。例如,当您的JVM使用的是America/Toronto
时区(考虑EST/EDT)而MySQL服务器使用的是固定区域偏移量时,事情可能会变得混乱,例如UTC-4
(不考虑标准/夏令时)。Gord Thompson的评论是正确的,并说明为什么永远不要使用麻烦的遗留类,如java.sql.Date
、java.util.Date
、和Calendar
。
LocalDateTime ldt = myResultSet.getObject( … , OffsetDateTime.class ) ;
LocalDate ld = ldt.toLocalDate() ;