【问题标题】:Android - SQLite - SELECT BETWEEN Date1 AND Date2Android - SQLite - 在 Date1 和 Date2 之间选择
【发布时间】:2013-01-08 02:50:40
【问题描述】:

Mac OS-X

安卓

带有 ADT 的 Eclipse

SQLite

我是创建 Android 应用程序的新手,我对此进行了大量研究,但我一无所获。我需要查询我的 SQLite 数据库以返回两个日期之间的所有行。到目前为止,我从研究中了解到,Androids SQLite 数据库中没有 DateTime 列,我必须将其保存为文本列。但我认为问题在于尝试比较字符串,但我无法找到解决方法。这是我的代码:

DB = currentContext.openOrCreateDatabase(DBName, 0, null);
DB.execSQL("CREATE TABLE IF NOT EXISTS " + tableName + " (ID INTEGER PRIMARY KEY AUTOINCREMENT, Date VARCHAR(40), Hours INT(3));");

我没有收到任何错误,但我没有从我的 RawQuery 返回任何结果。这是我的代码:

Cursor c = newDB.rawQuery("select ID, Date, Hours from " + tableName + " where Date BETWEEN '" + date1 + " 00:00:00' AND '" + date2 + " 99:99:99'", null);

if (c != null ) {
  Log.d(TAG, "date1: "+date1);
  Log.d(TAG, "date2: "+date2);
  if  (c.moveToFirst()) {
     do {
        int id = c.getInt(c.getColumnIndex("ID"));
        String date1 = c.getString(c.getColumnIndex("Date"));
        int hours1 = c.getInt(c.getColumnIndex("Hours"));
        results.add(+ id + "    Date: " + date1 + "    Hours: " + hours1);
     }
         while (c.moveToNext());
      }
}

我也尝试了以下语句,但它们也没有产生结果:

Cursor c = newDB.rawQuery("select ID, Date, Hours from " + tableName + " where Date BETWEEN " + Date(date1) + " AND " + Date(date2) + "", null);

我从其他 StackOverflow 答案中得到了这个声明,但我找不到关于 date() 方法的任何文档。我不确定它现在是否已过时,但我收到错误消息“类型(类名)的日期(字符串)方法未定义”,我已尝试导入一些 JAVA 库。

有谁知道创建 rawData() 查询的正确方法,该查询将获取所选日期之间的行??

更多信息,这些是我的 INSERT 语句和进入数据库的日期格式:

newDB.execSQL("INSERT INTO " + tableName + " (Date, Hours) Values ('" + ph_date + "'," + hours + ");");
String date1 = "12/1/13"
String date2 = "25/1/13"

【问题讨论】:

  • SQLite 的发明者explained 确实是为了light 目的,更多的是作为普通文件的替代品,而不是作为一个严肃的数据库。对于更严肃的工作,请考虑纯 Java H2 Database Engine,Android 作为支持的平台已讨论 here

标签: java android sqlite date android-sqlite


【解决方案1】:

好的,所以我无法让字符串日期工作,所以我必须在将它们添加到 SQLite 数据库之前将字符串日期转换为日历日期到 Unix 时间,并在显示时将它们转换回来(Unix 时间到日历日期到字符串)他们。 Unix Time 允许在日期列上进行计算(排序、升序、介于等),这是经过长时间反复试验后使用的最佳方法。这是我最终使用的代码:

Cursor c = newDB.rawQuery("select ID, Date, Hours from " + tableName + " where Date BETWEEN '" + startDateQueryDate + "' AND '" + endDateQueryDate + "' ORDER BY Date ASC", null);

            if (c != null ) {
                if  (c.moveToFirst()) {
                    do {
                        int tempId = c.getInt(c.getColumnIndex("ID"));
                        long tempUnixTime = c.getLong(c.getColumnIndex("Date"));

                        //convert tempUnixTime to Date
                        java.util.Date startDateDate = new java.util.Date(tempUnixTime);

                        //create SimpleDateFormat formatter
                        SimpleDateFormat formatter1;
                        formatter1 = new SimpleDateFormat("dd/MM/yyyy", Locale.UK);

                        //convert Date to SimpleDateFormat and convert to String
                        String tempStringStartDate = formatter1.format(startDateDate);

                        int tempHours = c.getInt(c.getColumnIndex("Hours"));
                        results.add(+ tempId + "    Date: " + tempStringStartDate + "    Hours: " + tempHours);
                    }while (c.moveToNext());
                }
            }

【讨论】:

    【解决方案2】:

    您必须以understood by SQLite 格式存储日期值。 对于普通日期,这将是 YYYY-MM-DD 字符串、秒值或儒略日期数字。

    要将日期格式化为字符串,请使用以下内容:

    Date date1 = ...;
    DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
    String dateAsString = df.format(date1);
    

    要将日期格式化为秒值,请将 Date.getTime() 的返回值除以 1000。


    如果您的日期变量已经是字符串,则必须确保它们具有正确的格式。

    如果您的日期字符串没有yyyy-MM-dd 格式,SQLite 的date functions 将无法理解它们,并且无法进行比较(因为字符串必须以最重要的字段开头,年份,并且所有字段都必须具有固定长度,以便字符串比较正确)。

    【讨论】:

    • 所以您是说我可以比较字符串,但必须使用您提到的给定方法将它们作为 DateFormat 字符串放入 SQLite 数据库?这样我仍然可以使用相同的 rawQuery 语句吗?
    • 我收到错误:01-08 21:34:28.120:E/AndroidRuntime(26265):致命异常:主要 01-08 21:34:28.120:E/AndroidRuntime(26265):java。 lang.RuntimeException: 无法启动活动 ComponentInfo{com.example.tescoapp2/com.example.tescoapp2.DataListView}: java.lang.IllegalArgumentException 01-08 21:34:28.120: E/AndroidRuntime(26265): at android.app .ActivityThread.performLaunchActivity(ActivityThread.java:2243) 01-08 21:34:28.120: E/AndroidRuntime(26265): 由: java.lang.IllegalArgumentException 01-08 21:34:28.120: E/AndroidRuntime(26265) : 在 java.text.DateFormat.format(DateFormat.java:365)
    • 从 SQLite 的角度来看,日期字符串只是字符串。但是,字符串必须采用 SQLite 内置日期函数能够理解的格式,并且要正确比较两个日期字符串,最重要的字段年份必须排在第一位。
    • 我假设date1 的类型是Date。如果是Calendar,则使用date1.getTime()
    • date1 只是字符串类型。
    【解决方案3】:

    2 天内获得前两名

    Calendar cal = Calendar.getInstance();
                Date now = new Date();
                cal.setTime(now);
                String currentDate = sdf.format(cal.getTimeInMillis());
                cal.add(Calendar.DAY_OF_YEAR, -1);
                String previusdDate = sdf.format(cal.getTimeInMillis());
    
                Log.e("Start date", currentDate);
                Log.e("End date", previusdDate);
                SQLiteOpenHelper helper;
                SQLiteDatabase db;
                helper = new My_SQliteHelper(mContext, "MyDB", null, 1);
                db = helper.getWritableDatabase();
    
                Cursor cr = db.rawQuery("SELECT name,sum(minutes),date FROM Historyinfo WHERE date BETWEEN '" + previusdDate + "' AND '" + currentDate + "' GROUP BY name ORDER BY SUM(minutes) DESC LIMIT 2", null);
    

    100% 正常工作

    【讨论】:

      【解决方案4】:

      不确定您在哪里读到日期/时间应该存储为字符串!!! 我不同意。

      我更喜欢将日期/时间存储为 INTEGER 值。阅读:http://www.sqlite.org/datatype3.html#datetime

      插入数据时,将您的日期/时间转换为 Unix 时间,即自 1970-01-01 00:00:00 UTC 以来的秒数。例如2012 年 1 月 1 日 00:00:00 GMT 表示为 1356998400000

      Android Date/Calendar 类具有在 UNIX Times 中转换日期的内置函数,反之亦然。

      检查:http://developer.android.com/reference/java/util/Date.html#getTime%28%29

      选择时,您可以使用正常的选择语句,例如 BETWEEN 或您喜欢的任何内容。

      我已经用了很多年了,它就像一个魅力:D

      【讨论】:

      • getTime not 返回秒值。
      • here应该以文本或整数数据格式存储。
      猜你喜欢
      • 2019-09-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-09-27
      • 1970-01-01
      相关资源
      最近更新 更多