How to fetch data between 2 dates in greenDao database - android

I have two dates . One is the current date and the other is 30 days back date. So I need to fetch the data between these 2 dates in Green Dao. But I am not getting the result.
MyCode:
Date startRangeDate = new Date();
Date endRangeDate = dateBefore30Days;
QueryBuilder<StructSamePage> qb = UserDao.queryBuilder();
qb.where(UserDao.Properties.dateTime.between(startRangeDate.getTime(), endRangeDate.getTime()));
List<StructSamePage> list = qb.list();

Try swapping dates you pass.
Date startRangeDate = new Date();
Date endRangeDate = dateBefore30Days;
QueryBuilder<StructSamePage> qb = UserDao.queryBuilder();
qb.where(UserDao.Properties.dateTime.between(endRangeDate.getTime(),startRangeDate.getTime() ));
List<StructSamePage> list = qb.list();
Generally between works if left hand side value is smaller than right hand side

The WhereCondition between in GreenDao uses this:
/** Creates an "BETWEEN ... AND ..." condition for this property. */
public WhereCondition between(Object value1, Object value2) {
Object[] values = { value1, value2 };
return new PropertyCondition(this, " BETWEEN ? AND ?", values);
}
So you should just have to change your dates accordingly. Because you are using NOW first and the day 30 days before later your code would do this:
Value >= NOW AND Value <= 30 DAYS BEFORE
If you use actual dates wich greenDAO does not use! Your code would look like this:
today = 2016-03-04
30DaysAgo = 2016-02-03
WHERE dateTime >= 2016-03-04 AND dateTime <= 2016-02-03
So you should be fine if you just change your order.
If you want to know more about how BETWEEN works you can read this
A word of advice: greenDao uses timestamps as INTEGERS in the database so if you use java Dates you get a Date that also has a time (when it was created) if you just remove 30 days from it you will not include the whole day 30 days ago but only the day from the time the current date object was created in time. So maybe you want to create the Date from a Calendar without a time.

Related

Room Query BETWEEN dates doesnt return result

I am working on an application where i practice working with Room Persistence Library.
I have a class called expence based on which is the database with fields int amount and Date dob and other.
My goal is to use query below to return the sum of all entries between these dates.
#Query("SELECT SUM(amount) FROM expence WHERE dob BETWEEN date( :start ) AND date( :end ) ")
int newallexpensesFromTo(String start,String end);//
But at the curent state the query doesnt return anything and the textview i want to display the result = 0;
I have used guidance from http://androidkt.com/datetime-datatype-sqlite-using-room/ - to be able to convert from strings to Date and revese.
I have checked maybe its due to different format of the stored date and its the same the one stored in database and the one passed to query.
This is where i try to get the sum of the entries
value2 =db.expenceDao().newallexpensesFromTo(firstdayofmonth,lastdayofmonth);
I have a similar query where without the dates and it returns all entries.
When i add an expense i use DatePicker to add the Date to the dob in database.
Expected result is to receive the sum of entries added between these dates when the query receives the strings with the dates.
Try converting and inserting your startDate and endDate as a long timestamp value into your expense table instead of storing it in some another format.
Now while querying the data, use the timestamp values of your query dates.
For e.g., if you want SUM(amount) between 01-05-2019 and 31-05-2019 than your query would be like:
#Query("SELECT SUM(amount) FROM expense WHERE dob BETWEEN :startDate AND :endDate")
int newAllExpensesFromTo(Long startDate,Long endDate);
Where your startDate and endDate values will be something like 1556668800 & 1559260800 respectively.
For now you can use type converters.
As described in docs for Date your converter in Java should looks like below
public class Converters {
#TypeConverter
public static Date fromTimestamp(Long value) {
return value == null ? null : new Date(value);
}
#TypeConverter
public static Long dateToTimestamp(Date date) {
return date == null ? null : date.getTime();
}
}
To apply them, add below code above the class inheriting from RoomDatabase()
#TypeConverters({Converters.class})
Finally you will be able to use it like that
#Query("SELECT SUM(amount) FROM expence WHERE dob BETWEEN :from AND :to")
int newallexpensesFromTo(from: Date, to: Date)

Parse String to Date and then compare Dates

I am working on a Adaptive To-Do application, In this user will have a button to reschedule the pending tasks(Tasks with past date), when the user clicks reschedule, it'll change the pending tasks date to current free date(Dates which are not assigned to any task. What i cant understand is how to retrieve date from database and compare it with the available dates.But formater shows error, and if comparision also.
public void UpdateData() {
Calendar cal = Calendar.getInstance();
SQLiteDatabase db = mHelper.getReadableDatabase();
Cursor cursor = db.query(TaskContract.TaskEntry.TABLE_NAME,
new String[]{TaskContract.TaskEntry._ID,
TaskContract.TaskEntry.COLUMN_DATE,
},
null, null, null, null, null);
//Calendar reminderCalendar = Calendar.getInstance();
//reminderCalendar.set(year, month, day);
SimpleDateFormat formatter = new SimpleDateFormat("dd/MM/yyyy");
String str1 = TaskContract.TaskEntry.COLUMN_DATE;
Date date1 = formatter.parse(str1);//Show Error UnHandled Exception java.text.parse exception.
if (date1.before(cal))// Shows error and says to flip to (cal.before(date1)) {
ContentValues cv = new ContentValues();
final Calendar c = Calendar.getInstance();
int yy = c.get(Calendar.YEAR);
int mm = c.get(Calendar.MONTH);
int dd = c.get(Calendar.DAY_OF_MONTH);
}
}
String str1 = TaskContract.TaskEntry.COLUMN_DATE;
Assuming your column is called MYDATE, your code is saying that str1 = "MYDATE";
Can you tell me what date MYDATE is? Nor can the formatter, hence the exception.
I believe what you want is:-
String str1 = "";
if (cursor.moveTofirst) {
str1 = cursor.getString(cursor.getColumnIndex(TaskContract.TaskEntry.COLUMN_DATE));
} else {
// handle no data being extracted for some reason
}
cursor.close(); // assuming you've done with the Cursor
Date date1 = formatter.parse(str1);
..........
To further explain when you say :-
`Cursor cursor = db.query(......`
You are saying get me a cursor from the table(1st parameter), with the columns (2nd parameter, null for all columns), 3rd parameter where clause and so on.
If it works you will get a Cursor named cursor which contain your data as a number of rows of columns (like a spreadhsheet).
To get to the data you need to do the equivalent of get the data from cell A1 (A being the first column of the first row).
However you move to a Row and then get the nth column using one the get???? methods. Above move's to the first row (we'd only expect the 1 row by the looks of your code (more later)).
At a row you can get data from columns by using the index/offset to that column. The first column being 0, the next 1 etc.
However, having to work this out and perhaps change it if you change the query can introduce difficulties, so it's probably much easier to find the index/offest by using the column name. Hence, getColumnIndex(column_name_as_a_string)
Back to moving, to explain why the moveToFirst is in an if.
A cursor can contain 0 or more rows, a cursor, if the query works will not be null, rather an empty cursor is returned (this is a relatively frequent occurrence, and also sometimes a very useful situation).
So rather than issuing an exception because a Cursor can't move to a position, it returns false (true if it can and does move).
So if(cursor.moveToFirst) {....} is saying only do if there is data in the cursor.
There are other move methods, moveToLast(), moveToNext(), moveToPrevious() and moveToPosition(int).
Perhaps the most common is moveToNext e.g.
while(cursor.moveToNext()) {
// use the respective column data here
}
traversing all rows of the cursor

Android SQlite: Querying table rows by date range from today backwards?

I get a date from the server in "MM/dd/yyy" form, then I convert it into milliseconds using the following function:
public static long getSimpleDateToMillis(String simpleDate) throws ParseException {
SimpleDateFormat formatter = new SimpleDateFormat("MM/dd/yyyy");
Date date = formatter.parse(simpleDate);
return date.getTime();
}
Then afterwards I save the result into the database as int.
Right now I'm stucked in what seems like a dead-end for me. I can't find a way through searching and from my stock knowledge on how I would be able to filter my cursorloader by project_date column which is saved as integer in the database.
In what way would I be able to query such that it would:
Select all row from projects table where the project_date is today and backwards (yesterday and so on).
I tried this one but seems to be really not the answer.
String [] projection = new String []{};
String selection = "datetime("+ ProjectsEntry.COLUMN_PROJECT_DATE + "/1000, 'unixepoch') =? ";
String [] selectionArgs = new String[]{" date('now')"};
return new CursorLoader(this,
JobsContract.JobsEntry.CONTENT_URI,
projection,
selection,
selectionArgs,
null);
I haven't found any other reference that would point me, so I'm hoping someone might also have encountered this perhaps.
This is how I do something quite similar, but using full timesteamp i.e. long rather than int.
First I have this method to get the TimeStamp, to get today's date/time as of midnight (bar 1 millisecond):-
/**
*
* #return 1 millsecond before midnight today
*/
private long getDateTimeOfAllofToday() {
Calendar cal = Calendar.getInstance();
cal.add(Calendar.DAY_OF_MONTH,1); // tomorrow
cal.set(Calendar.MILLISECOND,0);
cal.set(Calendar.SECOND,0);
cal.set(Calendar.MINUTE,0);
cal.set(Calendar.HOUR_OF_DAY,0);
cal.add(Calendar.MILLISECOND,-1);
return cal.getTimeInMillis();
}
Then I create the respective where clause e.g. :-
filter = DBRulesTableConstants.RULES_ACTON_COL +
" <= " +
Long.toString(getDateTimeOfAllofToday());
This is used via a rawQuery so not exactly what you want but easy enough to to change " <= " to " <=?" and then use
String [] selectionArgs = new String[]{Long.toString(getDateTimeOfAllofToday())}; or a modified version to get integer.

How get data by month using DBFlow?

I'm facing some problems trying get a list of months and a list of data by month from my database in my app. Now I'm using strftime() function from SQLite but apparently the strftime() doesn't work.
For building and managing the database I'm using DBFlow ORM and the query of the first list looks like that.
List<ExpenseAndIncome> expenseAndIncomes = new Select("strftime('%Y-%m-%d', date").from(ExpenseAndIncome.class).queryList();
SELECT `strftime('%Y-%m-%d', date)` FROM `expense_and_income`
In this case it shows up an exception
android.database.sqlite.SQLiteException: no such column: strftime('%Y-%m-%d', date) (code 1): , while compiling: SELECT `strftime('%Y-%m-%d', date)` FROM `expense_and_income`
The other problem occurs when I'm trying to get a list of data by month. In this case the query looks like that.
List<ExpenseAndIncome> expenseAndIncomes = new Select().from(ExpenseAndIncome.class).where("strftime('%m', date) = ?", calendar.get(Calendar.MONTH)).groupBy("date").queryList();
SELECT * FROM `expense_and_income` WHERE strftime('%m', date) = 7 GROUP BY date
But the result always is a empty array.
Can someone helpe me?
strftime is just a function that formats a Date variable as a string. For example, strftime('%Y-%m-%d', date) might return '2015-08-17'.
Your query, then, is being evaluated as:
SELECT 2015-08-17 FROM expense_and_income
That's not really what you want. I imagine you want something more like:
SELECT UNIQUE month FROM expense_and_income
Assuming you have a field called month, that is.
Your second query is being evaluated as
SELECT * FROM expense_and_income WHERE 08 = 7 GROUP BY date
Obviously, 8 != 7, so while this is a valid query, it never returns anything. You probably want something more like
SELECT * FROM expense_and_income WHERE month = 08
I figured out how to solve one of the problems, getting a list of data by months.
When Android executes the following line in SQLite
List<ExpenseAndIncome> expenseAndIncomes = new Select().from(ExpenseAndIncome.class).where("strftime('%m', date) = ?", calendar.get(Calendar.MONTH)).groupBy("date").queryList();
Query representation
SELECT * FROM `expense_and_income` WHERE strftime('%m', date) = 7 GROUP BY date
They compare something like that
SELECT * FROM `expense_and_income` WHERE '08' = 7 GROUP BY date
And this occurs because my date table save the dates as string and calendar.get(Calendar.MONTH) returns an int as month representation and that int starts from 0. So, august is represented by the int 7 not 8 nor string '08'. SQLite query compares '08' with int 7 and because of this that array always are returned empty.
To solve this problem I created a method that returns a correct string representation to use in query comparison. The final code looks something like this:
List<ExpenseAndIncome> expenseAndIncomes = new Select().from(ExpenseAndIncome.class).where("strftime('%m', date) = ?", getMonthAsString(calendar.get(Calendar.MONTH))).groupBy("date").queryList();
private String getMonthAsString(int month) {
if (month > 0 && month < Constants.OCTOBER)
return Constants.ZERO + (Integer.toString(month) + 1);
return Integer.toString((month + 1));
}

Order list of dates in String format

I've got a list which contains x records with dates. The thing is all my dates are in the String format and come as strings from the database.
I would really like to order my List by date (in String format) but I really have no clue how to do this.
Without further ado, this is my list, which is a custom list.
List<Finance> finances;
The list contains following fields:
public class Finance {
private int id;
private int categoryId;
private int limitId;
private double amount;
private String date;
private String description;
}
And this is the dateformat I have (in String):
16/10/2013
15/12/2013
15/11/2013
14/9/2013
How would I be able to sort this custom list by date? I've seen many examples with Collections.sort but I cannot use that because of my custom list type.
I've also seen some examples with Comparable but I didn't really understand those..
Could anybody tell me what would be the best way to achieve a chronical order by date of mist list please?
I would also like the most lightweighted method, to use as little resources as I can.
EDIT: I still didn't find a working solution (19/12) and still hope for a response here..
Thank you
Yenthe
Okay since there where no good answers and barely any responses I decided to dig into it until I fixed it.
The 'easiest' way to come around this is to insert all your dates into the database as yyyy-mm-dd format. For a great explenation on that part you should look here: https://stackoverflow.com/a/5733535/2262409
When you place the date in yyyy-mm-dd and just do a order by Date in your SQLite the dates will be ordered correct. When you place them in dd-mm-yyyy they will not be ordered correct.
Long answer short:
Solved it in the SQL part. I insert records in the format yyyy-mm-dd I get them by
String selectQuery = "SELECT * FROM Finance ORDER BY date desc";
And then I reformat them to dd-mm-yyyy right before the user sees it. Example:
String date = String.valueOf(values.get(position).getDate());
// we will format yyyy-mm-dd to dd-mm-yyyy for readability.
//the sql has ordered our dates correctly already.
String firstPartDate = date.substring(8, 10);
String secondPartDate = "/" + date.substring(5,7);
String thirdPartDate = "/" + date.substring(0,4);
String fullCorrectDate = firstPartDate + secondPartDate + thirdPartDate;
Log.i("firstpart", firstPartDate + secondPartDate + thirdPartDate);
dateFinance.setText(fullCorrectDate);

Categories

Resources