SQLite JDBC rs.getDate()getTimestamp()等都返回错误的值

时间:2011-03-24 21:09:04

标签: sqlite datetime date jdbc timestamp

由于某种原因使用JDBC for SQLite时,Date和Timestamp值正确存储在DB中,在使用命令行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 =图灵
job =计算机
date = 1970-01-01
dateAsString = 2011-03-24

3 个答案:

答案 0 :(得分:8)

像Scott说:SQLite没有Date类型。

您可以让SQLite使用strftime函数为您进行转换:strftime('%s', date)。然后,您可以在Java端使用rs.getDate

您还可以将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();
}

答案 1 :(得分:2)

SQLite3没有Date类型,因此在编写代码时必须获取日期的字符串。

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

答案 2 :(得分:2)

SQLite不使用'类型'而是使用所谓的'类型亲和力&#39 ;;

来自documentation本身:

  

这里的重要思想是建议使用类型,而不是必需

您可以将日期存储为字符串,然后使用SimpleDateFormatDateTimeFormatter这样的格式化类来解析它们,或者您可以使用像Date.from(Instant.parse(rs.getString("date")))这样粗糙的内容。

Java 8

在这里的其他答案中,我要说LocalDate#parse()LocalDateTime#parse()也是Java 8向前发展的好选择。

他们接受String格式的日期

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

或者使用DateTimeFormatter作为第二个参数的字符串

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

转换

如果您希望使用LocalDateLocalDateTime但希望支持Date,则可能采用适配器模式;

到目前为止的LocalDateTime:

此示例使用系统默认时区作为atZone的ZoneId参数,但是如果需要,可以使用静态/硬编码时区。基本上你是从AtZone创建一个Instant,它可以用来从静态方法Date#from(Instant)

建立一个Date。
Date.from(localDate.atStartOfDay().atZone(ZoneId.systemDefault()).toInstant()));

LocalDate To Date:

这个例子几乎是一样的,只有这里获得ZoneId以创建Instant所需要的只是LocalDate实例本身。

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

我在这里没有进入技术细节,甚至可能没有必要,但如果我错了,请纠正我。