2017-10-12 7 views
0

Je vois des résultats inattendus lorsque j'essaie d'utiliser sqlite3 pour interroger des dates insérées via JDBC. Ce code java:Quelle est la bonne façon d'insérer des datetimes dans sqlite depuis java?

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(); 
    } 
} 

ne semble pas insérer un datetime correct - quand je l'interroger via sqlite3, je ne peux pas obtenir une valeur lisible par l'homme:

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

Cela est logique, depuis les docs sqlite disent que la gamme d'époque unix valide est "-62167219200 à 106751991167" (https://sqlite.org/lang_datefunc.html).

Comment utiliser les dates avec JDBC et Sqlite?

Répondre

0

Il n'existe pas de type de date ou d'horodatage formel dans SQLite, mais ceux-ci sont représentés par des chaînes. Donc, si vous voulez insérer l'horodatage en cours dans votre table, vous pouvez essayer ce qui suit:

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

je pouvais le faire, mais cela signifie que ma demande contient maintenant la logique de travailler autour de la représentation interne des dates en SQLite. Et rend mon code spécifique à sqlite. Il semble qu'il devrait y avoir une meilleure façon de laisser les spécificités d'implémentation de sqlite au pilote JDBC. –

+0

@MarkW Quel pilote utilisez-vous et pouvez-vous modifier votre question pour inclure un lien vers la documentation de ce pilote? –

+0

@MarkW [Voir ici] (https://stackoverflow.com/questions/5425557/sqlite-jdbc-rs-getdate-gettimestamp-etc-all-return-wrong-values) qui traite d'une question très similaire à la vôtre, et dont la conclusion est que les dates doivent être traitées comme des chaînes dans SQLite et Java. –

0

W @ Mark Nous avons mis les dates dans le SQLite DB en tant que chaînes, mais ils ne sont pas assez chaînes Ressemblant cette 10 18-2017 ils vont comme ça 10182017 et OUI ils ont tous 8 caractères. Mais quand vous les sortez, ils sont tous habillés et se transforment en ce 18-10-2017. Nous avons testé nos recherches et tout semble fonctionner comme vous le souhaitez avec le SELECT * FROM nom_table where Col_Date> = « de » ET Col_Date < = « à » Voici le code pour rendre la date pas assez

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(); 

ensuite, voici une façon de regarder la même chaîne 10182017 comme date de haute couture

 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); 
    }