Android - SQLite - SELECT BETWEEN Date1 AND Date2

18,655

Solution 1

Ok, so I could not get string dates to work, so I had to convert String Dates to Calendar Dates to Unix Time before adding them to the SQLite database and convert them back (Unix Time to Calendar Dates to String) when displaying them. Unix Time allows calculations (order by, sort ascending, between etc) done on the date columns and it is the best method to use after long hours of trial and error. Here is the code I ended up using:

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

Solution 2

You must store date values in a format understood by SQLite. For plain dates, this would be a YYYY-MM-DD string, or a seconds value, or a Julian date number.

To format a date as string, use something like this:

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

To format a date as seconds value, divide the return value of Date.getTime() by 1000.


If your date variables already are strings, you must ensure that they have the correct format.

If your date strings do not have the yyyy-MM-dd format, SQLite's date functions will not understand them, and comparisons will not work (because the string must begin with the most significant field, the year, and all fields must have a fixed length, so that string comparisons come out correct).

Solution 3

getting top two name of for 2 days

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% working

Share:
18,655
Phil Hunter
Author by

Phil Hunter

Just trying to program my way out of this Matrix.

Updated on July 16, 2022

Comments

  • Phil Hunter
    Phil Hunter almost 2 years

    Mac OS-X

    Android

    Eclipse with ADT

    SQLite

    I'm new to creating Android Apps and Ive researched this heavily but I'm getting nowhere. I need to query my SQLite database to return all the rows between 2 dates. What I have learnt from my research so far is that there is no DateTime column in Androids SQLite database and I have to save it as a text column. But I think the problem lies with trying to compare Strings but I can't figure out a way around it. Here is my code :

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

    I am not getting any errors but I am not returning any results from my RawQuery. Here is my code:

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

    I have also tried the following statement but they do not yield results either:

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

    I got this statement from other StackOverflow answers but I cannot find any documentation on the date() method. Im not sure whether it is obsolete now but I get error saying "Date(String) method is undefined for the type (classname)" and I have tried importing some JAVA Libraries.

    Does anyone know the correct way to create a rawData() query that will get the rows between selected dates??

    Further info, these are my INSERT statements and the date format that goes into the database:

    newDB.execSQL("INSERT INTO " + tableName + " (Date, Hours) Values ('" + ph_date + "'," + hours + ");");
    String date1 = "12/1/13"
    String date2 = "25/1/13"
    
  • Wirsing
    Wirsing over 11 years
    getTime does not return a seconds value.
  • Phil Hunter
    Phil Hunter over 11 years
    So you are saying I CAN compare Strings BUT they must be put into the SQLite database as a DateFormat String using the given method you mentioned? This way I can still use my same rawQuery statement?
  • Phil Hunter
    Phil Hunter over 11 years
    Says here it should be stored as text or integer data format.
  • Phil Hunter
    Phil Hunter over 11 years
    I get error: 01-08 21:34:28.120: E/AndroidRuntime(26265): FATAL EXCEPTION: main 01-08 21:34:28.120: E/AndroidRuntime(26265): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.tescoapp2/com.example.tescoapp2.Da‌​taListView}: java.lang.IllegalArgumentException 01-08 21:34:28.120: E/AndroidRuntime(26265): at android.app.ActivityThread.performLaunchActivity(ActivityThr‌​ead.java:2243) 01-08 21:34:28.120: E/AndroidRuntime(26265): Caused by: java.lang.IllegalArgumentException 01-08 21:34:28.120: E/AndroidRuntime(26265): at java.text.DateFormat.format(DateFormat.java:365)
  • Wirsing
    Wirsing over 11 years
    From SQLite's point of view, date strings are just strings. However, strings must be in that format to be understood by SQLite's built-in date functions, and to compare two date strings correctly, the most-significant field, the year, must come first.
  • Wirsing
    Wirsing over 11 years
    I assume date1 is of type Date. If it is Calendar, use date1.getTime().
  • Phil Hunter
    Phil Hunter over 11 years
    date1 is just of type String.
  • Dev4Life
    Dev4Life over 2 years
    Wow! It worked with charm! I didn't expecct it after trying lots of different approach, but using date in yyyy-MM-dd actually works. Saved my day!