【问题标题】:SQLite Android time querySQLite Android 时间查询
【发布时间】:2022-01-18 06:28:41
【问题描述】:

我正在使用 Android 应用程序并想查询我的 SQLite 数据库。

我有文本类型的“时间”列。

ID = 49, date = 2021-12-15, time = 03:43:16, ...
ID = 50, date = 2021-12-15, time = 03:54:35, ...
ID = 51, date = 2021-12-15, time = 03:56:32, ...

我需要查询某个时间段内的数据。例如,从 07:00:00 到 10:00:00

我做了这个查询函数:

public void dbQuery(String startTime, String stopTime, Integer number) {
        dbHelper = new DBHelper(this);
        String selection = null;
        
        SQLiteDatabase db = dbHelper.getWritableDatabase();
        Log.d(LOG_TAG, "--- Connected myDB: ---");

        selection = "number = " + "\'" + number + "\'"+ " and " +  "time between " + "\'" + startTime + "\'" + " and " +  "\'" + stopTime + "\'";

        c = db.query("MyDB", null, selection, null, null, null,null);
}

我读到如果日期\时间数据写成文本类型,你可以随意查询,比如你的数据是日期Java格式。 但是有这个:

W/System.err: java.text.ParseException: Unparseable date: "07:00:00"

我的查询失败了。

那么,在 SQLite 中进行时间查询的方法是什么?

【问题讨论】:

    标签: java android sqlite android-sqlite


    【解决方案1】:

    那么,在 SQLite 中进行时间查询的方法是什么?

    我需要查询某个时间段内的数据。例如,从 07:00:00 到 10:00:00

    根据您的数据,您不会发现任何行,因为 03:43:16 等不在范围内。否则您的查询工作正常。

    W/System.err: java.text.ParseException: Unparseable date: "07:00:00" 的问题不在查询中,而是在其他地方。您似乎正在尝试从某个时间开始日期,而解析器拒绝了它。

    • (例如,哪个月是 00,一个月中的哪一天是 00)

    当您尝试将时间解析为日期时,这会在其他地方发生。

    演示

    考虑以下哪个

    a) 表明您的查询有效 b) 演示改进的查询 d) 演示获取您遇到的错误的示例

    @SuppressLint("Range")
    public class MainActivity extends AppCompatActivity {
        static final String LOG_TAG = "LOGDBINFO";
        DBHelper dbHelper;
        Cursor c;
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
    
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            dbQuery("01:00:00","19:00:00",1);
            while(c.moveToNext()) {
                Log.d(LOG_TAG+"RUN1",
                        "Number is " + c.getString(c.getColumnIndex("number")) +
                                " Date is " + c.getString(c.getColumnIndex("date")) +
                                " Time is " + c.getString(c.getColumnIndex("time"))
                );
            }
            improvedQuery("01:00:00","19:00:00",1);
            while(c.moveToNext()) {
                Log.d(LOG_TAG+"RUN2",
                        "Number is " + c.getString(c.getColumnIndex("number")) +
                                " Date is " + c.getString(c.getColumnIndex("date")) +
                                " Time is " + c.getString(c.getColumnIndex("time"))
                );
            }
            /* reposition the cursor  before the first row */
            c.moveToPosition(-1);
            while (c.moveToNext()) {
                try {
                    Date ok = sdf.parse(c.getString(c.getColumnIndex("date")) + " " + c.getString(c.getColumnIndex("time")));
                    //Date test = sdf.parse(c.getString(c.getColumnIndex("date"))); // Fails as no time
                    Date test2 = sdf.parse(c.getString(c.getColumnIndex("time")));
                } catch (ParseException e) {
                    e.printStackTrace();
                }
            }
        }
    
        public void dbQuery(String startTime, String stopTime, Integer number) {
            dbHelper = new DBHelper(this);
            String selection = null;
    
            SQLiteDatabase db = dbHelper.getWritableDatabase();
            Log.d(LOG_TAG, "--- Connected myDB: ---");
    
            selection = "number = " + "\'" + number + "\'"
                    + " and " +  "time between " + "\'" + startTime + "\'"
                    + " and " +  "\'" + stopTime + "\'"
                    ;
    
            c = db.query("MyDB", null, selection, null, null, null,null);
        }
    
        /* This Binds the values passed which reduces the chance for SQLite Injection and
            also encloses the passed values in single quotes as required
         */
        public void improvedQuery(String startTime, String stopTime, Integer number) {
            SQLiteDatabase db = dbHelper.getWritableDatabase();
            c = db.query(
                    "MyDB",null,
                    "number =? AND time between ? AND ?",
                    new String[]{String.valueOf(number),startTime,stopTime},
                    null,null,null);
        }
    }
    

    在查询日志后运行循环时:-

    D/LOGDBINFO: --- Connected myDB: ---
    D/LOGDBINFORUN1: Number is 1 Date is 2021-12-15 Time is 03:43:16
    D/LOGDBINFORUN1: Number is 1 Date is 2021-12-15 Time is 03:54:35
    D/LOGDBINFORUN1: Number is 1 Date is 2021-12-15 Time is 03:56:32
    

    改进后的查询日志:-

    D/LOGDBINFORUN2: Number is 1 Date is 2021-12-15 Time is 03:43:16
    D/LOGDBINFORUN2: Number is 1 Date is 2021-12-15 Time is 03:54:35
    D/LOGDBINFORUN2: Number is 1 Date is 2021-12-15 Time is 03:56:32
    

    但是在没有遇到线路问题后:-

    Date ok = sdf.parse(c.getString(c.getColumnIndex("date")) + " " + c.getString(c.getColumnIndex("time")));
    

    在该行中捕获一个异常:-

    Date test2 = sdf.parse(c.getString(c.getColumnIndex("time")));
    

    这是您遇到的异常,即日志显示:-

    W/System.err: java.text.ParseException: Unparseable date: "03:43:16"
    W/System.err:     at java.text.DateFormat.parse(DateFormat.java:362)
    W/System.err:     at a.a.so70357434.MainActivity.onCreate(MainActivity.java:50)
    
    • 请注意,最后一条消息详细说明了确切的行,在 Android Studio 中,它还有一个链接,如果单击该链接会将您带到有问题的行。
    • 因此,在询问存在异常的问题时,为什么要包含堆栈/日志。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-11-11
      • 2012-03-06
      • 2015-08-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-12-25
      相关资源
      最近更新 更多