【问题标题】:What is the correct way to insert datetimes into sqlite from java?从java将日期时间插入sqlite的正确方法是什么?
【发布时间】:2017-10-12 14:48:41
【问题描述】:

当我尝试使用 sqlite3 查询通过 JDBC 插入的日期时,我看到了意外的结果。这个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();
    }
}

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

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

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

我应该如何在 JDBC 和 Sqlite 中使用日期?

【问题讨论】:

    标签: java datetime sqlite


    【解决方案1】:

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

    【讨论】:

    • 我可以这样做,但这意味着我的应用程序现在包含处理 Sqlite 中日期的内部表示的逻辑。并使我的代码特定于 sqlite。似乎应该有更好的方法将 sqlite 实现细节留给 JDBC 驱动程序。
    • @MarkW 您正在使用哪个驱动程序,您可以编辑您的问题以包含指向该驱动程序文档的链接吗?
    • @MarkW See here 讨论了一个与您的问题非常相似的问题,其结论是日期需要在 SQLite 和 Java 中作为字符串处理。
    【解决方案2】:

    @Mark W 我们一直将日期作为字符串放在 sqlite DB 中,但它们并不是像 2017 年 10 月 18 日这样漂亮的字符串,它们像 10182017 一样进入,是的,它们都是 8 个字符长。但是,当您将它们拉出时,它们会全部打扮并变回 2017 年 10 月 18 日。我们已经测试了我们的搜索,所有似乎都可以使用 SELECT * FROM TABLE_NAME WHERE Col_Date >= "from" AND 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);
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-04-10
      • 1970-01-01
      • 1970-01-01
      • 2023-03-28
      • 2010-12-28
      • 1970-01-01
      相关资源
      最近更新 更多