ResultSet getDate() 返回不正确和正确的日期

ResultSet getDate() is returning incorrect and correct dates

我正在根据 table 的假期创建 LocalDate 的列表。数据库 table 中的日期都是正确的,但是当我使用 ResultSet getDate() 方法并使用所有日期填充列表时,其中 4 个日期是错误的,6 个是正确的。我正在寻找任何帮助来弄清楚为什么会这样。

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]

这里是数据库table信息。这是非常基础的。

CREATE TABLE holidays( 
province VARCHAR(255), 
holiday VARCHAR(255), 
fulldate DATETIME);

INSERT INTO holidays(province, holiday, fulldate) VALUES
('Ontario', 'New Years', '2019-01-01'), 
('Ontario', 'Family Day', '2019-02-18'), 
('Ontario', 'Good Friday', '2019-04-19'), 
('Ontario', 'Victoria Day', '2019-05-20'), 
('Ontario', 'Canada Day', '2019-07-01'), 
('Ontario', 'Civic Holiday', '2019-08-05'), 
('Ontario', 'Labour Day', '2019-09-02'), 
('Ontario', 'Thanksgiving', '2019-10-14'), 
('Ontario', 'Christmas Day', '2019-12-25'), 
('Ontario', 'Boxing Day', '2019-12-26');

// This is the select result from the query above

+---------------------+
|       fulldate      |
+---------------------+
| 2019-01-01 00:00:00 |
+---------------------+
| 2019-02-18 00:00:00 |
+---------------------+
| 2019-04-19 00:00:00 |
+---------------------+
| 2019-05-20 00:00:00 |
+---------------------+
| 2019-07-01 00:00:00 |
+---------------------+
| 2019-08-05 00:00:00 |
+---------------------+
| 2019-09-02 00:00:00 |
+---------------------+
| 2019-10-14 00:00:00 |
+---------------------+
| 2019-12-25 00:00:00 |
+---------------------+
| 2019-12-26 00:00:00 |
+---------------------+

如您所见,列表两端的 2 个日期不正确。我假设 getDate() 方法正在发生某些事情。任何人都可以阐明这一点吗?干杯。

为什么要将可怕的遗产 class Date 与现代的 LocalDate 混在一起?你为什么要投射 (Date)?

SQL-标准DATE

如果您的列的类型类似于 SQL-标准 DATE,则将 LocalDate 与符合 JDBC 的 JDBC 驱动程序一起使用4.2 或更高版本。

LocalDate ld = myResultSet.getObject( … , LocalDate.class ) ;

SQL-标准TIMESTAMP WITH TIME ZONE

如果您的专栏是类似于 SQL-标准 TIMESTAMP WITH TIME ZONE 的类型,那么您必须考虑时区以确定日期。

OffsetDateTime odt = myResultSet.getObject( … , OffsetDateTime.class ) ;
ZoneId z = ZoneId.of( "Australia/Sydney" ) ;
ZonedDateTime zdt = odt.atZoneSameInstant( z ) ;
LocalDate ld = zdt.toLocalDate() ;

SQL-标准TIMESTAMP WITHOUT TIME ZONE

如果您的列的数据类型类似于 SQL-标准 TIMESTAMP WITHOUT TIME ZONE,例如 MySQL 类型 DATETIME,请使用 Java输入 LocalDateTime。这种类型只有日期和时间,没有时区或与 UTC 的偏移量。所以这个类型 而不是 代表一个时刻。

LocalDateTime ldt = myResultSet.getObject( … , OffsetDateTime.class ) ;
LocalDate ld = ldt.toLocalDate() ;