SQLite JDBC rs.getDate () getTimestamp () и т. Д. Все возвращают неправильные значения - PullRequest
5 голосов
/ 25 марта 2011

При использовании JDBC для SQLite по какой-то причине значения Date и Timestamp правильно хранятся в БД, правильно отображаются при использовании инструмента командной строки sqlite3, но при использовании функций ResultSet для получения этих значений это не работает.Ниже приведен небольшой тестовый класс, который демонстрирует, что я имею в виду.

import java.sql.*;

public class Test {
  public static void main(String[] args) throws Exception {
    Class.forName("org.sqlite.JDBC");
    Connection conn = DriverManager.getConnection("jdbc:sqlite:test.db");
    Statement stat = conn.createStatement();
    stat.executeUpdate("drop table if exists people;");
    stat.executeUpdate("create table people (name, occupation, date date);");
stat.executeUpdate("insert into people values ('Turing', 'Computers', date('now'));");

    ResultSet rs = stat.executeQuery("select * from people;");
    while (rs.next()) {
      System.out.println("name = " + rs.getString("name"));
      System.out.println("job = " + rs.getString("occupation"));
      System.out.println("date = " + rs.getDate("date"));
      System.out.println("dateAsString = " + rs.getString("date"));
    }
    rs.close();
    conn.close();
  }
}

Вывод, который я получаю:

name = Turingработа = компьютерыдата = 1970-01-01dateAsString = 2011-03-24

Ответы [ 3 ]

8 голосов
/ 25 марта 2011

Как говорит Скотт: SQLite не имеет типа Date.

Вы можете сделать так, чтобы SQLite сделал преобразование за вас с помощью функции strftime : strftime('%s', date). Тогда вы можете использовать rs.getDate на стороне Java.

Вы также можете получить дату SQLite в виде строки и преобразовать ее в дату:

DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
try {
    Date today = df.parse(rs.getString("date"));
    System.out.println("Today = " + df.format(today));
} catch (ParseException e) {
   e.printStackTrace();
}
2 голосов
/ 25 мая 2016

SQLite не использует «типы» и вместо этого использует так называемое «сходство типов»;

Из самой документации :

Важная идеяздесь этот тип рекомендуется, а не обязателен

Вы можете хранить даты в виде строк и анализировать их по своему усмотрению с помощью классов форматирования, таких как SimpleDateFormat или DateTimeFormatter, или вы можете использовать что-то грубоекак Date.from(Instant.parse(rs.getString("date"))).

Java 8

Среди других ответов здесь я бы сказал, что LocalDate#parse() и LocalDateTime#parse() также является хорошим вариантом для продвижения вперед в Java 8.

Они принимают дату в строковом формате

LocalDate.parse("2016-05-24")

или строку со значением DateTimeFormatter в качестве второго аргумента

LocalDate.parse("2016-05-24", DateTimeFormatter.ofPattern(yyyy-MM-dd))


Преобразование

И если вы хотите использовать LocalDate или LocalDateTime, но хотите поддержать Date, возможно, в шаблоне адаптера ;

LocalDateTime to Date:

В этом примере системный часовой пояс по умолчанию используется в качестве аргумента ZoneId atZone, однакоВы можете использовать статический / жестко закодированный часовой пояс, если хотите.По сути, вы создаете Instant из AtZone, который можно использовать для построения Date из статического метода Date#from(Instant)

Date.from(localDate.atStartOfDay().atZone(ZoneId.systemDefault()).toInstant()));

LocalDate To Date:

Этот пример почти такой же,только здесь все, что требуется для получения ZoneId для создания Instant, - это сам экземпляр LocalDate.

Date.from(localDate.atZone(ZoneId.systemDefault()).toInstant()));

Я не вдавался в технические подробности здесь, это может даже не бытьнеобходимо, но поправьте меня, если я ошибаюсь.

2 голосов
/ 25 марта 2011

SQLite3 не имеет типа Date, поэтому вам придется получать строку дат при написании кода.

http://www.sqlite.org/datatype3.html

...