I have a "small" problem. I have a SQLiteDatabase ("PLB") with a table called "Flights". In this table i have a column called "Total_Flight_Time"type TIME which memorize time in HH:MM format. I wanna make a SUM of the hours and minutes. Something like 01:20 + 01:50 = 03:10 (HH:MM) but i don't know how to do it.
I found a code here, on stackoverflow:
Function from DBAdapter:
public Cursor getTotalTime() throws SQLException {
return db.rawQuery("SELECT sum(strftime('H%:%M', Total_Flight_Time) - strftime('H%:%M', '00:00')), 'unixepoch' FROM Flights",null);
}
Function call in main activity (it should show the SUM result in a Text View):
DBHelper.open();
TextView txt = (TextView)findViewById(R.id.textView22);
String total = DBHelper.getTotalTime().toString();
txt.setText(total);
But on the Screen it shows: android.database.sqlite.SQLiteCursor#41aa42b8
How do i have to do the function and the function call to fix the problem, i wan it to show HH:MM? :)
SOLVED!
SOLUTION:
DBAdapter function:
public Cursor getTotalTime() throws SQLException {
return db.rawQuery("SELECT time(sum(strftime('%s', Total_Flight_Time) - strftime('%s','00:00:00')),'unixepoch') FROM Flights",null);
}
Function Call in Main Activity:
TextView txt = (TextView)findViewById(R.id.textView22);
Cursor c = DBHelper.getTotalTime();
c.moveToFirst();
String[] names = c.getColumnNames(); // inspect this as it should have a length of 1
String total = c.getString(c.getColumnIndex(names[0]));
txt.setText(total);
This is the source of your problems:
In this table i have a column called "Total_Flight_Time" type TIME which memorize time in HH:MM format.
You're misusing TIME data type because your Total_Flight_Time is actually storing a duration, not a point in time. Change the type for Total_Flight_Time to integer, representing the number of seconds or the number of minutes in the duration. Then summing up your durations become a trivial matter of integer sums. A little arithmetic will allow you to transform number of seconds/minute to days, hours, minutes, and seconds.
db.rawQuery(...) returns type Cursor so you are calling cursor.toString() which results in what you see. You need to use a function of the Cursor class to extract the results of your query and then display the results. eg:
you may have to move the cursor to the first row in which case it will look like this:
Cursor c = DBHelper.getTotalTime();
c.moveToFirst();
String total = c.getString(0);
if you dont know the column index (and its not 0) try:
Cursor c = DBHelper.getTotalTime();
c.moveToFirst();
String[] names = c.getColumnNames() // inspect this as it should have a length of 1
String total = c.getString(c.getColumnIndex(names[0]));
If names.length != 1 let me know the results.
I think this (or some variation of this) should help. See the documentaion of the Cursor class for more details: http://developer.android.com/reference/android/database/Cursor.html
comment response:
c.moveToFirst();
while (c.isAfterLast() == false) {
Log.w("query Test", "result: " + cur.getString(0);
c.moveToNext();
}
SimpleDateFormat formatter = new SimpleDateFormat("HH:MM");
Date curDate = formatter.parse(DBHelper.getTotalTime().toString());
long curMillis = curDate.getTime();
Then, you can add this to some other date (again converting that to long) and display the sum in the date format.
Related
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
hello guys for the last three days I have been working on a simple query , but it is just not working , I'm trying to prevent register departure without having registered arrival , here is the code in my DB helper,not sure what is wrong with that query!!
public Boolean HasShowedUpToday(int check_id)
{
Boolean attend;
SQLiteDatabase db=this.getWritableDatabase();
SimpleDateFormat dateFormat = new SimpleDateFormat("dd-MM-yyyy", Locale.getDefault());
time=Calendar.getInstance().getTime();
String dateoftoday= dateFormat.format(time);
Cursor c = db.rawQuery("SELECT * FROM attendance where user_id = '"+check_id+"' and arrival_time ='"+dateoftoday+"' and departure_time ='';", null);
if (c.moveToFirst())
{
attend=true;
}
else
{
attend=false;
}
return attend;
}
First of all do not construct queries like that. This is very wrong habit which will made you in future to write code which is vulnerable to SQL injections.
Use rawQuery (String sql, String[] selectionArgs).
So it should look like this:
Cursor c = db.rawQuery("SELECT * FROM attendance where user_id = ? and arrival_time = ? and departure_time IS NULL",
new String[] { check_id, dateoftoday} );
Also take a look on this SO answer. And this answer looks even better - store dates as number of milliseconds since EPOCH time.
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.
I have SQLite table named "Att_Table" with 5 columns:
id
name
date
timein
timeout
I have inserted data in these columns through two different Activity (using insert and update). Now I want to calculate the time difference between timeout and timein column so that I can calculate the total working hours.
I also want to display that result in a EditText.
This method is in DatabaseHelper class:
public Cursor workinghours() {
final String TABLE_NAME = "attendance";
SQLiteDatabase db = this.getReadableDatabase();
String selectQuery = "SELECT total(strftime('%s', timeout) - strftime('%s', timein) FROM" +TABLE_NAME+ "WHERE _id='2' ";
Cursor cursor = db.rawQuery(selectQuery, null);
return cursor;
}
The emulator shows the error in query(syntax error). I am new in android programming and I couldn't find any tutorial on this topic on internet so I tried this my self with some pieces of codes.
This method is in activity:
public void working_hours() {
Cursor result = mydb.workinghours();
w_hours.setText(result.toString());
}
w_hours is EditText where I want to show the total working hours.
I'm new here, sorry if I have done something stupid.
SQLite stores datetime as String. That's why your code is not working because Strings can not be subtracted from each other.
You need to Parse the String time as Java Time object, then calculate the difference in Java instead of SQLite.
The following method can help. You need to save your Time Strings in 24 hours format for best result.
public static String getTimeDuration(String StartTime24, String EndTime24)
{
String duration = "";
try
{
SimpleDateFormat parseFormat = new SimpleDateFormat("HH:mm");
Date startTime = parseFormat.parse(StartTime24);
Date endTime = parseFormat.parse(EndTime24);
long mills = endTime.getTime() - startTime.getTime();
long minutes = mills/(1000 * 60);
duration = "Difference is: " + minutes + " Minutes";
}
catch(ParseException ex)
{
// exception handling here
}
return duration;
}
Iam trying to find average of a column in my sqlite database.
Here is the code:
public void getAvgMileage(Prediction pd)
{
String [] columns = new String[]{KEY_ROW_ID, KEY_KM, KEY_FUEL_QTY, KEY_FUEL_PRICE, KEY_TOTAL_COST, KEY_MILEAGE, KEY_DATE,KEY_TANK_FULL};
predictionCursor = ourDatabase.rawQuery("SELECT AVG(_mileage) FROM fuel_table WHERE _mileage IS NOT NULL ORDER BY _id DESC LIMIT 5", null);
predictionCursor.moveToFirst();
if(predictionCursor!=null && predictionCursor.getCount()>0)
{
predictionCursor.moveToLast();
findAvgMileage = (Double.valueOf(predictionCursor.toString()));
pd.setpredictionMileage(findAvgMileage);
}
}
But Iam geting a NullPointerException.
Any help??
Thank you.
It doesn't look like you are getting the value out of the cursor for your SQL recordset
This line:
findAvgMileage = (Double.valueOf(predictionCursor.toString()));
looks like it's trying to take a double value of the tostring() of the actual cursor - which I don't think is going to usable or at least not parseable to Double. The return of Cursor.toString() may well be a null value.
replace the line with the following:
findAvgMileage = predictionCursor.getDouble(0);
This new line will fetch out the value in the first column of the current position of the curosr which in your SQL should be the average value you want.