Search code examples
javaandroidandroid-sqlite

I think I have come up with the worst way to compare two dates; is it possible to make it better?


My app accepts a date form the user through a datepicker fragment and stores it in a database with the day, month and year as individual columns of type String.

Now, I'm creating a function which will later check each of these dates with the current date of the system. If the current date is ahead of the date entered by the user (and stored in the database) a flag variable is incremented.

Here is the code:

public int checkDate() {                                    //Method to check date and take action
                                                                                //NOT COMPLETE. STILL FIGURING IT OUT.  

        String isstatus = "Ongoing";
        String[] columns = new String[] {KEY_ROWID, DAY, MONTH, YEAR ,PROJECT_STATUS}; 
        Cursor c = projectDatabase.query(DATABASE_TABLE, columns, PROJECT_STATUS + "=" + isstatus, null, null, null, null);
        int result = 0;
        int flag = 0;

        int iRow = c.getColumnIndex(KEY_ROWID);
        int iDay = c.getColumnIndex(DAY);
        int iMonth = c.getColumnIndex(MONTH);
        int iYear = c.getColumnIndex(YEAR);

        final Calendar cal = Calendar.getInstance();                        //fetch current system date
        int cyear = cal.get(Calendar.YEAR);
        int cmonth = cal.get(Calendar.MONTH);
        int cday = cal.get(Calendar.DAY_OF_MONTH);


        for(c.moveToFirst(); !c.isAfterLast(); c.moveToNext()) {

            String id = c.getString(iRow);

            int fday = Integer.parseInt(c.getString(iDay));
            int fmonth = Integer.parseInt(c.getString(iMonth));
            int fyear = Integer.parseInt(c.getString(iYear));

            if(cday>fday && cmonth>fmonth && cyear>fyear) {

                flag++;
                updateStatus(id, "Missed");

            }

               else

            if(cday>fday && cmonth==fmonth && cyear==fyear) {

                flag++;
                updateStatus(id, "Missed");

            }

               else

            if(cday==fday && cmonth>fmonth && cyear>fyear) {

                flag++;
                updateStatus(id, "Missed");

            }

               else

            if(cday==fday && cmonth==fmonth && cyear>fyear) {

                    flag++;
                    updateStatus(id, "Missed");

            }

               else

            if(cmonth>fmonth && cyear>fyear) {

                    flag++;
                    updateStatus(id, "Missed");

            }

               else

            if(cmonth>fmonth && cyear==fyear) {

                    flag++;
                    updateStatus(id, "Missed");

            }

            result = flag;


        }


        return result;
    }

As you can see, I have to compare every possible case for the date being ahead. And I personally think it's not the most efficient method. Any advice?


Solution

  • I've never really worked with dates, but I'll outline an algorithm that at least reduces the number of comparisons you need to make.

    if(currentYear > dataYear) {
        //We're obviously past that date. Move on
    } else if(currentYear == dataYear) {
        //We're in the same year. Let's check for months
        if(currentMonth > dataMonth) {
            //Missed the date again, move on
        } else if(currentMonth == dataMonth) {
            //We're in the same year and the same month! Let's check days
            if(currentDay > dataDay) {
                //Date is still in the past. Keep moving on
            } else if(currentDay == dataDay) {
                //Date is today
            } else {
                //Date is in the future
            }
        }
    } else {
        //Date is in the past
    }
    

    This isn't going to be terrible efficient either, and you could probably cut down on the number of if statements by using && strategically (though compiler optimization might do it for you anyways).

    A better approach would be to save the date in UNIX time, and get the current UNIX time and just compare the two longs. Can't get much simpler than that.

    You could also construct another Calendar object from your stored date and use before(). However, a primitive long vs long comparison will be more efficient than comparing two Calendars.