从java中将日期时间插入sqlite的正确方法是什么?

问题描述:

当我尝试使用sqlite3查询通过JDBC插入的日期时,我看到意外的结果。这java代码:从java中将日期时间插入sqlite的正确方法是什么?

try (Connection conn = DriverManager.getConnection("jdbc:sqlite:test.db")) { 
    conn.setAutoCommit(true); 
    try (Statement statement = conn.createStatement()) { 
     statement.executeUpdate("create table dates (date DATETIME);"); 
    } 

    try (PreparedStatement insert = conn 
      .prepareStatement("insert into dates values (?)")) { 
     insert.setTimestamp(1, Timestamp.valueOf(LocalDateTime.now())); 
     insert.executeUpdate(); 
    } 
} 

似乎没有插入正确的日期时间 - 当我通过sqlite3的查询它,我不能让人类可读的值:

sqlite3 test.db "select date, datetime(date, 'unixepoch') from dates;" 
1507819362296| 

这是有道理的,因为sqlite文档说有效的unix时代范围是“-62167219200到106751991167”(https://sqlite.org/lang_datefunc.html)。

我该如何使用JDBC和Sqlite的日期?

SQLite中没有正式的日期或时间戳类型,而是由字符串表示。所以,如果你想为当前的时间戳插入到你的表,你可以尝试以下方法:

try (Connection conn = DriverManager.getConnection("jdbc:sqlite:test.db")) { 
    conn.setAutoCommit(true); 
    try (Statement statement = conn.createStatement()) { 
     statement.executeUpdate("CREATE TABLE dates (date TEXT);"); 
    } 

    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 
    Timestamp timestamp = new Timestamp(System.currentTimeMillis()); 
    String ts = sdf.format(timestamp); 

    try (PreparedStatement ps = conn 
      .prepareStatement("INSERT INTO dates (date) VALUES (?)")) { 
     ps.setString(1, ts); 
     ps.executeUpdate(); 
    } 
} 
+0

我能做到这一点,但它意味着我的应用程序现在包含逻辑来解决SQLite中日期的内部表示。并使我的代码特定于sqlite。 似乎应该有一个更好的方法来将sqlite实现细节留给JDBC驱动程序。 –

+0

@MarkW您正在使用哪种驱动程序,并且可以编辑您的问题以包含该驱动程序文档的链接? –

+0

@MarkW [见这里](https://stackoverflow.com/questions/5425557/sqlite-jdbc-rs-getdate-gettimestamp-etc-all-return-wrong-values),其讨论了一种非常类似的问题到你的,并其结论是日期需要在SQLite和Java中作为字符串处理。 –

@马克W¯¯我们一直把日期在sqlite的DB为字符串,但是他们不是很期待这样的字符串10 18-2017他们进来像这样10182017和是的他们都是8个字符长。但是当你把它们拉出来时,他们都会穿上衣服并转换回这个10-18-2017。我们已经测试了我们的搜索和所有似乎与SELECT *所需FROM TABLE_NAME工作WHERE Col_Date> =“再从” Col_Date < =“到”下面是制作日期不那么漂亮的代码

public void findByDate(View view){ 
    use= false; 
    // custom dialog /* THIS R.style.DatePickerThem is mandatory to use res/values/styles */ 
    final Dialog dialog = new Dialog(MainActivity.this,R.style.DatePickerTheme); 
    dialog.setContentView(R.layout.datepickerview); 
    dialog.setTitle(""); 
    DatePicker picker = dialog.findViewById(R.id.datePicker); 
    final Calendar c = Calendar.getInstance(); 
    mYear = c.get(Calendar.YEAR); 
    mMonth = c.get(Calendar.MONTH); 
    mDay = c.get(Calendar.DAY_OF_MONTH); 
    //picker.updateDate(2017, 10, 13);//year month day 
    picker.updateDate(mYear, mMonth, mDay);// Keeps Calendar initial view what ever today is! 

    System.out.println("Month " + mMonth+1); 

    picker.init(c.get(Calendar.YEAR), c.get(Calendar.MONTH), c.get(Calendar.DAY_OF_MONTH), new DatePicker.OnDateChangedListener() { 
     //picker.init(Integer.valueOf(mMonth),Integer.valueOf(mDay),Integer.valueOf(mYear), new DatePicker.OnDateChangedListener() { 
     @Override 
     public void onDateChanged(DatePicker picker, int year, int monthOfYear, int dayOfMonth) { 

      if (etFromDate.getText().toString().isEmpty()) { 
       System.out.println("I am Not Empty"); 

       //etFromDate.setText(String.valueOf(monthOfYear+1) + String.valueOf(dayOfMonth) + String.valueOf(year)); 
       //v1 = Long.valueOf(etFromDate.getText().toString()); 
       //etFromDate.setText(String.valueOf(v1)); 
       //String theDATE = (monthOfYear+1) + "-" + (dayOfMonth) + "-" + (year); 
       String searchFrom = (String.valueOf(monthOfYear+1))+(String.valueOf(dayOfMonth))+String.valueOf(year); 
       if(searchFrom.length()==7){ 
        StringBuilder str = new StringBuilder(searchFrom); 
        str.insert(2, '0'); 
        etFromDate.setText(str); 
       }else if (searchFrom.length() == 6){ 
        StringBuilder str = new StringBuilder(searchFrom); 
        str.insert(0,'0'); 
        str.insert(2,'0'); 
        etFromDate.setText(str); 
       }else { 
        etFromDate.setText(searchFrom); 
       } 


       //setDATE = etFromDate.getText().toString(); 
       dialog.dismiss(); 

然后这里是一个方式来看待相同的字符串10182017的高级时装日期

 helper = new DBHelper(this); 
    dbList = new ArrayList<>(); 
    dbList = helper.getDataFromDB(); 

    if (dbList.size() > 0 && tORf.equalsIgnoreCase("false")) { 

     btnSave.setVisibility(View.INVISIBLE); 
     String NVrowid = String.valueOf(dbList.get(position).getRowid()); 
     String NVstation = dbList.get(position).getStation_Name(); 
     String NVpurchasedate = dbList.get(position).getDate_of_Purchase(); 
     String s = NVpurchasedate; 
     String month = s.substring(0, 2); 
     String day = s.substring(2, 4); 
     String year = s.substring(4, 8); 
     String date3 = month + "-" + day + "-" + year; 
     String NVcost = dbList.get(position).getGas_Cost(); 
     etStation.setText(NVstation); 
     etPurchaseDate.setText(date3); 
     //etPurchaseDate.setText(NVpurchasedate); 
     etCost.setText(NVcost); 
    }