-1

I'm facing a problem while running a query which retrieves data from database for a given period of time.
The idea is that the user chooses 2 different dates (from , to) and then a ListView is populated with the data retrieved from a SQLite database - this data being between the from and to dates.
The query works perfectly without the WHERE clause, but when I try setting the date range, it fails.

I have stored the dates in SQLite in this format M/d/yyyy 12:00:00 AM.
While I send the dates (parameters) to the SELECT statement in this format yyyy-MM-dd.

I don't know how to deal with this.

Here is my code:

    public class ProductionCommentsActivity extends Activity implements View.OnClickListener {
    private DBHandler dbHandler;
    private ListView listView;
    private Context context;
    private ArrayList<String> results = new ArrayList<String>();
    private ArrayAdapter adapter;
    private static String newline = System.getProperty("line.separator");
    private EditText editTextFrom, editTextTo;
    private DatePickerDialog datePickerDialogFrom, datePickerDialogTo;
    private SimpleDateFormat simpleDateFormat;
    private String fromDate,toDate ; // variables to store the chosen dates


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_production_comments);



        dbHandler = new DBHandler(this, dbHandler.DATABASE_NAME_PRODUCTION, null, 1);
        try {
            dbHandler.copyDataBase();
            Log.d("copydb", dbHandler.getDatabaseName());
        } catch (IOException e) {
            e.printStackTrace();
            Log.d("copydb",e.getMessage());
        }

        //defining list view
        listView = (ListView) findViewById(R.id.listView);

        //defining edit texts properties
        editTextFrom = (EditText) findViewById(R.id.editTextFrom);
        editTextFrom.setInputType(InputType.TYPE_NULL);
        editTextFrom.requestFocus();

        editTextTo = (EditText) findViewById(R.id.editTextTo);
        editTextTo.setInputType(InputType.TYPE_NULL);

        //setting up the date format
        simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd", Locale.US);
        setDateTimeField();
        context = this;
    }

    //method to handle the date pickers properties
    private void setDateTimeField() {
        editTextFrom.setOnClickListener((View.OnClickListener) ProductionCommentsActivity.this);
        editTextTo.setOnClickListener((View.OnClickListener) ProductionCommentsActivity.this);

        //creating a new instance of the calendar
        Calendar newCalendar = Calendar.getInstance();

        //creating a pop up date picker
        datePickerDialogFrom = new DatePickerDialog(this, new DatePickerDialog.OnDateSetListener() {

            //getting the chosen date and setting its format
            //and writing the chosen date in the edit text
            public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) {
                Calendar newDate = Calendar.getInstance();
                newDate.set(year, monthOfYear, dayOfMonth);
                editTextFrom.setText(simpleDateFormat.format(newDate.getTime()));
                fromDate = editTextFrom.getText().toString();
            }

        },newCalendar.get(Calendar.YEAR), newCalendar.get(Calendar.MONTH),
                newCalendar.get(Calendar.DAY_OF_MONTH));

        datePickerDialogTo = new DatePickerDialog(this, new DatePickerDialog.OnDateSetListener() {

            public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) {
                Calendar newDate = Calendar.getInstance();
                newDate.set(year, monthOfYear, dayOfMonth);
                editTextTo.setText(simpleDateFormat.format(newDate.getTime()));
                toDate = editTextTo.getText().toString();


            }

        },newCalendar.get(Calendar.YEAR), newCalendar.get(Calendar.MONTH),
                newCalendar.get(Calendar.DAY_OF_MONTH));
    }

    // on click method to handle which edit text was touched
    // and show the appropriate pop up calendar
    @Override
    public void onClick(View view) {
        if(view == editTextFrom) {
            datePickerDialogFrom.show();
        } else if(view == editTextTo) {
            datePickerDialogTo.show();
        }
    }

    public void searchDates(View view){
        setDateTimeField();
        try {
           // getProductionComments(fromDate, toDate);
            getProductionComments(fromDate,toDate);

            adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, results);
            listView.setAdapter(adapter);
        }catch(Exception ex){
            Toast.makeText(this, ex.getMessage(), Toast.LENGTH_LONG).show();
        }


    }

    //get production comments data
    private void getProductionComments(String from, String to) {
        try {
            SQLiteDatabase db = dbHandler.getReadableDatabase();


            String query = "SELECT Date,Item,Comments FROM ProductionCommentData WHERE Date BETWEEN "+ from +
                    "AND "+ to+";";
            Cursor cursor = db.rawQuery(query,null);

            if (cursor != null) {
                if (cursor.moveToFirst()) {
                    do {
                        String date = cursor.getString(cursor.getColumnIndex("Date"));
                        String item = cursor.getString(cursor.getColumnIndex("Item"));
                        String comments = cursor.getString(cursor.getColumnIndex("Comments"));

                        results.add("Date: " + date.substring(0, 9) + newline + newline  +
                                "Item: " + item + newline + newline  + "Comments: " + comments);
                    } while (cursor.moveToNext());
                }
            }
        } catch (SQLiteException se){
            Log.e(getClass().getSimpleName(), "Error retrieving data from database");
        }
    }
Phantômaxx
  • 37,901
  • 21
  • 84
  • 115
user3804193
  • 113
  • 4
  • 11
  • `I have dates stored in sqlite database file in this format M/d/yyyy 12:00:00 AM` But did you read this? [SQLite TimeStrings](https://www.sqlite.org/lang_datefunc.html) – Phantômaxx Sep 16 '15 at 10:45

2 Answers2

2

You should store your Date as long value in database. Simple new Date().getTime() gives you this value and new Date(long value) returns it back. So you can make such queries easy.

Viktor Yakunin
  • 2,927
  • 3
  • 24
  • 39
  • It's not necessary. Using the proper [SQLite TimeString](https://www.sqlite.org/lang_datefunc.html) is easier. – Phantômaxx Sep 16 '15 at 10:46
  • 1
    I have good news for you: **no string comparison is needed**. Just use the SQLite date functions and/or the BETWEEN clause. Hope you learned something new. – Phantômaxx Sep 16 '15 at 10:53
  • 1
    @ViktorYakunin `long` data type doesn't exist in sqlite! what do you mean by "long value" ? – user3804193 Sep 16 '15 at 10:53
  • 2
    @user3804193 He means INTEGER, I guess. – Phantômaxx Sep 16 '15 at 10:54
  • @FrankN.Stein how many data types are in sqlite? 4 - int, real, blob, text. All the rest are converted to text. So, it is not clear, but using int type to store your date and compare it to Date.getTime() gives you much better performance than to store SimpleDateFormat, convert your Date to String and perform Between which is String comparison operation. – Viktor Yakunin Sep 16 '15 at 10:59
  • @FrankN.Stein what do you think i should do? what do you suggest? – user3804193 Sep 16 '15 at 10:59
  • @user3804193 Something like this answer: http://stackoverflow.com/a/9649747/2649012 – Phantômaxx Sep 16 '15 at 11:00
  • @user3804193 long type for Java code and int for sqlite http://stackoverflow.com/questions/8672473/is-there-type-long-in-android-sql – Viktor Yakunin Sep 16 '15 at 11:00
  • 2
    @ViktorYakunin I don't find a **number of milliseconds** representing a date being very **human friendly**. But something like this is: `SELECT * FROM Categories WHERE DateCreated BETWEEN '2012-03-11 00:00:00' AND '2015-05-12 23:59:59'` – Phantômaxx Sep 16 '15 at 11:02
  • 1
    @FrankN.Stein Agree it is not friendly, but if your column name is something like 'timestamp' or 'eventDate' it is more clear what the number means. Your solution is working no doubts - post it as answer and I will vote for it :) – Viktor Yakunin Sep 16 '15 at 11:07
1

What I can suggest is to:

  • Export your table to CSV,
  • Change the date values to a proper SQLite TimeString and
  • Re-import the CSV after deleting the original table.

Then, you can run a query like:

SELECT * FROM Categories WHERE DateCreated BETWEEN '2012-03-11 00:00:00' AND '2015-05-12 23:59:59'

See this answer, which is better, because it uses bound parameters.

Community
  • 1
  • 1
Phantômaxx
  • 37,901
  • 21
  • 84
  • 115