I am saving the data with the date it was filed, but the date I inset changes to the current date
When you save the data
Calendar currentDate=Calendar.getInstance();
DatabaseOperations DB = new DatabaseOperations(ctx);
DB.putInformation(DB, done_today1 + "\n" + done_today2 + "\n" + done_today3, thankful_for1 + "\n" + thankful_for2 + "\n" + thankful_for3 + "\n" + thankful_for4 + "\n" + thankful_for5, for_relationship, for_kids, for_business, currentDate.get(Calendar.DATE) + "-" + currentDate.get(Calendar.MONTH) + "-" + currentDate.get(Calendar.YEAR));
Inserts the data into the table
public void putInformation(DatabaseOperations dop,String happenedToday,String thankfulFor,String forRelationship,String forKids,String forBusiness,String currentDate){
SQLiteDatabase SQ=dop.getWritableDatabase();
ContentValues cv=new ContentValues();
cv.put(TableData.TableInfo.DONE_TODAY, happenedToday);
cv.put(TableData.TableInfo.THANKFUL_FOR,thankfulFor);
cv.put(TableData.TableInfo.FOR_RELATIONSHIP,forRelationship);
cv.put(TableData.TableInfo.FOR_KIDS,forKids);
cv.put(TableData.TableInfo.FOR_BUSINESS,forBusiness);
cv.put(TableData.TableInfo.CURRENT_DATE,currentDate);
SQ.insert(TableData.TableInfo.TABLE_NAME, null, cv);
Log.d("Database operations", "One Row Inserted");
And when I retrieve the date this way
Cursor CR = dop.getInformation(dop);
CR.moveToFirst();
Toast.makeText(DisplayTable.this,""+CR.getString(5),Toast.LENGTH_LONG).show();
I am getting the current date and not the date that the data was filed in.
Any one knows why is it happening?
In SQL, CURRENT_DATE is a keyword that refers to the current date.
To access a column with the same name, you have to quote the column name (double quotes are for identifiers; single quotes are for strings):
> CREATE TABLE t(current_date);
> INSERT INTO t VALUES('x');
> SELECT current_date FROM t;
2015-09-28
> SELECT "current_date" FROM t;
x
> SELECT 'current_date' FROM t;
current_date
It might be a better idea to use a different column name.
Best way to handle date and times is to always use ISO standard timestamps, the ones with T and Z. This makes translating actual dates within different time zones easy.
One way also is saving date and times using unix timestamp, its a long integer that can be translated to the actual dates of different time zones, so it will reflect always the correct time based on your time zone.
Related
I want to retrieve data of last week or 30 days from my SQLite database, and show it in a ListView. I tried different queries but did not get result. So how can I get data of only last 30 days?
Create database table query :
public String CREATE_DATA_TABLE="CREATE TABLE "+TABLE_DATA+"("
+ DATE + " TEXT," + TIME+ " TEXT,"+STEPS + " TEXT,"+CALORIES +" TEXT," +
DISTANCE+ " TEXT"+")";
Storing data :
public boolean storeData(String date,String time,long stepsTaken,
long caloriesBurned, String distanceCovered){
SQLiteDatabase db=this.getWritableDatabase();
ContentValues values=new ContentValues();
values.put(DATE, date);
values.put(TIME, time);
values.put(STEPS, stepsTaken);
values.put(CALORIES, caloriesBurned);
values.put(DISTANCE, distanceCovered);
long result=db.insert(TABLE_DATA,null, values);
if(result==-1)
return false;
else
return true;
}
Getting data, the query I try to retrieve data is in comment line :
public ArrayList<User> getData(){
calendar=Calendar.getInstance();
dateFormat=new SimpleDateFormat("yyyy-MM-dd");
date=dateFormat.format(calendar.getTime());
ArrayList<User> arrayList= new ArrayList<>();
SQLiteDatabase db=getReadableDatabase();
//String query="SELECT * FROM "+ TABLE_DATA+" WHERE date BETWEEN datetime('now','-30 days') AND datetime('now', 'localtime')";
//Cursor cursor=db.rawQuery(query,null);
Cursor cursor=db.rawQuery("SELECT * FROM "+TABLE_DATA,null);
while (cursor.moveToNext()){
String date=cursor.getString(0);
String time=cursor.getString(1);
long steps=cursor.getLong(2);
long calories=cursor.getLong(3);
String distance=cursor.getString(4);
User user=new User(date,time,steps,calories,distance);
arrayList.add(user);
}
return arrayList;
}
The way I get date and time :
calendar=Calendar.getInstance();
dateFormat=new SimpleDateFormat("dd-MM-yyyy");
timeFormat= new SimpleDateFormat("HH:mm:ss");
date=dateFormat.format(calendar.getTime());
time=timeFormat.format(calendar.getTime());
is it anyway that we can only store data of last 30 days
Your issue is that as the date column starts with the Day then this will be the first character compared so *02-01-1900 is greater than 01-12-2018. This is further complicated as you are using the datetime function that returns the date as YYYY-MM-DD so you are comparing 01-01-1990 with 2018-11-11 (less). However 21-01-1990 would be higher than 2018-11-11 (i.e. 21 is higher than 20).
Therefore you MUST have the dates in the same format for a comparison or sort to return results consistent with expectations.
You have two core solutions :-
Amend your code to store the dates in a a supported format, which just so happens to also suit comparisons and sorting (i.e. YYYY-MM-DD) see Time Strings - SQL As Understood By SQLite - Date And Time Functions.
In which case you query would then work if the date function rather then the datetime function were used as per String query="SELECT * FROM "+ TABLE_DATA+" WHERE date BETWEEN datee('now','localtime','-30 days') AND date('now', 'localtime')";
Reformat the date retrieved from the date column dynamically. e.g. by using :-
SELECT * FROM table_data WHERE
substr(date,7,4)||substr(date,3,4)||substr(date,1,2)
BETWEEN date('now','localtime','-30 days') AND date('now','localtime')
;
Note likewise you should apply the use of localtime consistently (as the above does, bar the date retrieved from the table which should have localtime applied when storing the value).
Proof of Concept
The following is some SQL that could be copied and pasted to an SQLite tool to show that the second option above works :-
DROP TABLE IF EXISTS table_data;
CREATE TABLE IF NOT EXISTS table_data (id INTEGER PRIMARY KEY, date TEXT);
INSERT INTO table_data (date) VALUES
(substr(date('now','localtime','-50 days'),9,2)||substr(date('now','localtime','-50 days'),5,4)||substr(date('now','localtime','-50 days'),1,4)),
(substr(date('now','localtime','-40 days'),9,2)||substr(date('now','localtime','-40 days'),5,4)||substr(date('now','localtime','-40 days'),1,4)),
(substr(date('now','localtime','-30 days'),9,2)||substr(date('now','localtime','-30 days'),5,4)||substr(date('now','localtime','-30 days'),1,4)),
(substr(date('now','localtime','-20 days'),9,2)||substr(date('now','localtime','-20 days'),5,4)||substr(date('now','localtime','-20 days'),1,4)),
(substr(date('now','localtime','-10 days'),9,2)||substr(date('now','localtime','-10 days'),5,4)||substr(date('now','localtime','-10 days'),1,4))
;
-- Result 1 (the data as loaded)
SELECT * FROM table_data;
-- Result2 Data extracted using BETWEEN
SELECT * FROM table_data
WHERE
substr(date,7,4)||substr(date,3,4)||substr(date,1,2)
BETWEEN date('now','localtime','-30 days') AND date('now','localtime')
;
-- Result 3 data from 30 days ago on
SELECT * FROM table_data WHERE
substr(date,7,4)||substr(date,3,4)||substr(date,1,2) >= date('now','localtime','-30 days')
;
Results :-
Result 1
(rows 3,4 & 5 with 30 days)
Result 2
Result 3
Although more time and space has been given to option 2. It is suggested that Option1 is by far the better option as it will reduce unnecessary complexity and be more efficient.
i want to get some data from my database by passing 2 values like
getdata("1","5");
My function in database and the id is stored as String in database.
getdata(String FromMember_id,String ToMember_id){
}
I have also cast the id to get data but I didnt get data
Query is
"SELECT * FROM MilkCollection WHERE cast(member_code as REAL)
BETWEEN '"+ FromMember_id + "' AND '" +ToMember_id+ "' ";
When is use this Query without casting
"SELECT * FROM MilkCollection WHERE member_code '"+ FromMember_id + "'
AND '" + ToMember_id + "'"
and when i dont cast the member_code and do the same query it shows data but it shows the other data other id like 17,18,19 i guess its taking the starting value of 17,18,19 because there is 1 in starting of them.
As i understand your issue, you need to type cast your passing values to REAL which sure gives you a workaround solutions.
"SELECT * FROM MilkCollection WHERE cast(member_code as REAL) >='"+ FromMember_id + "' AND cast(member_code as REAL) <= '" + ToMember_id + "' ";
Description: Just because you are passing string values using your member function which causes uncertainty while fetching data from your database.
Here is some working code for sending objects for a get. You can compare and see where you have taken a misstep.
public String getPreachLogString(long day, String time) {
String selectQuery;
SQLiteDatabase db;
Cursor cursor;
String myPath = DATABASE_PATH + DATABASE_NAME;
db = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READONLY);
selectQuery = "SELECT * FROM TABLE WHERE day = " + day + " AND time = \"" + time + "\"";
cursor = db.rawQuery(selectQuery, null);
To use strings in search I wrap string in \" where you wrap in '. Not sure why you are storing member IDs as string, assuming you have letters involved, but try casting member_code as TEXT to make a logical comparison between the 2 objects.
What you are trying to accomplish is possible I do it all the time. You just need to compare properly.
public ArrayList<String> getMonthlyWork(int year, int month) {
long thismonth = 0;
long nextmonth = 0;
String selectQuery;
SQLiteDatabase db;
ArrayList<String> result = new ArrayList<>();
SimpleDateFormat formatDate = new SimpleDateFormat("dd-MM-yyyy", Locale.US);
String myPath = DATABASE_PATH + DATABASE_NAME;
Calendar c = Calendar.getInstance();
c.set(year, month, 1);
thismonth = c.getTimeInMillis();
if (month < 11) {
c.set(Calendar.MONTH, month + 1);
} else {
c.set(Calendar.MONTH, 0);
c.set(Calendar.YEAR, year + 1);
}
nextmonth = c.getTimeInMillis();
db = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READONLY);
selectQuery = "SELECT * FROM TABLE WHERE day >= " + thismonth + " AND day < " + nextmonth;
Seems like John Bravdo already given you a working example
Let me address following 2 areas:
1. Why following SQL is not returning result?
Code:
"SELECT * FROM MilkCollection WHERE cast(member_code as REAL)
BETWEEN '"+ FromMember_id + "' AND '" +ToMember_id+ "' ";
With parameter value:
SELECT * FROM MilkCollection WHERE cast(member_code as REAL)
BETWEEN 1 AND 5;
Answer: Your table does not has any record containing value 1 to 5, but it does has record with value 17, 18, 19. Try pass the value 17 and 19 instead of 1 and 5, then it should return value. Moreover, test the SQL in database directly to confirm it does return data before checking in your program
Poor performance
Using a function call on any indexed column, e.g. cast(member_code as REAL), will not able to make use of index (regular index). Therefore, this SQL going to scan the entire table. You will start to see poor performance as the table size grow. Therefore, you need to use a column that is integer type in order to filter by integer value. You can add this column later after you have bandwidth. If the table is just a 1MB in disk, then you need to consider how many concurrent users are going to trigger this SQL call. If there are 1000 users running it concurrently, then it will cause 1GB of disk I/O (although DB engine could cache it) and it will be slow as well
I want to delete some records from android's database where two conditions are fulfilled.
1. there's a column with the name as sync_status, it should have a value 'C' and
2. there's column which has date.
Now I want to delete only those rows where sync_status is = 'c' and date is less than device's current date. I'm having problem in comparing the device's current date with the date stored in the database and my function deletes all the records.
public int RemoveSyncData(){
DBHelper = new DatabaseHelper(context);
DateFormat dateFormat = new SimpleDateFormat("MM-dd-yyyy ");
Calendar calObj = Calendar.getInstance();
String currentDate = dateFormat.format(calObj.getTime());
Log.e("current date",currentDate);
int rows = db.delete(DATABASE_TABLE_DAILY_ATTENDANCE, KEY_ATTENDANCE_SYN_STATUS + "= ? and " + KEY_ATTENDANCE_DATE_ONLY + " != '" + currentDate + "'", new String[] {"C"});
db.close();
return rows;
}
If you absolutely want to keep the date as a string in the form MM-DD-YYYY in your database column, then the only way to do comparison of those dates is to convert them to seconds using SQLite's strftime function. However, in order to do that, you have to restructure the date as YYYY-MM-DD because your current format is not one that can be used as input to the date and time functions of SQLite.
Here is a sample:
DateFormat dateFormat = new SimpleDateFormat("MM-dd-yyyy");
Calendar calObj = Calendar.getInstance();
String currentDate = dateFormat.format(calObj.getTime());
String where = KEY_ATTENDANCE_SYN_STATUS + " = ?1 AND "
+ "STRFTIME('%s', SUBSTR(" + KEY_ATTENDANCE_DATE_ONLY + ",7) "
+ "|| '-' || SUBSTR(" + KEY_ATTENDANCE_DATE_ONLY + ",1,5)) < "
+ "STRFTIME('%s', SUBSTR(?2,7) || '-' || SUBSTR(?2,1,5))";
String[] whereArgs = {"C", currentDate};
int rows = db.delete(DATABASE_TABLE_DAILY_ATTENDANCE, where, whereArgs);
If you use yyyy-MM-dd when creating currentDate, you can replace the second instance of the ugly substring + concatenation with just STRFTIME('%s', ?2), but you will still need the first substring + concatenation to transform the column values in the table.
If it's not too late for you to change how your database stores the date, make your life easier by either storing as yyyy-MM-dd (to get rid of all the substring + concatenation above), or better yet store the long date and only worry about converting it to and from MM-dd-yyyy at the java layer.
** EDIT **
Your condition is right it should delete only the rows that meet the condition, just tested it on my SQLite Viewer with some dummy data..
Just be 100% sure that your variable names match the column names and also check the database, if there are some rows which shouldn't be deleted. Maybe there is no entry for today's date and "C" is present in all rows thats why all the records are being deleted.
You can also try the "not so good way":
db.execSQL("delete FROM tableName WHERE KEY_ATTENDANCE_SYN_STATUS = 'C' AND KEY_ATTENDANCE_DATE_ONLY != '"+currentDate+"'");
The above is not a good way as execSQL won't return anything so you won't have anyway to know if it was successful except for checking it yourself.
The above approach is only to test your condition though.
I store date as TEXT in my database in this format YYYY-MM-DD.
Each row has start date and final date.
I want to select the row that today date is between the start date and final date.
Today date is string and is in the same format as those ex.2014-07-29
I've tried
SELECT * FROM TABLE_NAME WHERE date(todayDate) BETWEEN date(COLUMN_START_DATE) AND date(COLUMN_FINAL_DATE)
but it didn't work. I get 0 row.
I've also tried
SELECT * FROM TABLE_NAME WHERE strftime('%Y-%m-%d', todayDate) BETWEEN COLUMN_START_DATE AND COLUMN_FINAL_DATE
Still not work.
What am I doing wrong?
use this to get the results:-
String selection = "from_duration<=Datetime('" + initial_date
+ "') AND to_duration>=Datetime('" + final_date + "')";
your_database.query(Table_Name,Columns_youwant, selection,
null, null, null, null);
I am facing huge issues with running date-related queries on the local SQLite database, kindly appreciate your help on this!
I am trying to retrieve all events that have its eventdate within a given year and month. To do this, I calculated the first date and last date of that month, then queried where the event date is within this range.
My test data uses:
String[] testEventDates = {"2011-12-17", "2012-02-25", "2012-01-10", "2012-01-01",
"2011-12-24","2012-02-25"}
But when I run my query below, I get ALL of these entries retrieved, which is wrong. My query is, (SELECT...WHERE) "eventDate >= " + firstDay.
When I add the other limit, " AND "eventDate < " + lastDay,
it also works weirdly, the cursor is null instead.
Please help me if you have any clues about this!
// fetch events by month, between first and last days calculated
public Cursor fetchEventsByMonth(int month, int year) {
String firstDay, lastDay, correctedMonth;
if (month == 12) {
lastDay = Integer.toString(year+1) + "-01-01";
} else{
if (month+1 < 10) {
correctedMonth = "0" + Integer.toString(month+1);
} else correctedMonth = Integer.toString(month+1);
lastDay = Integer.toString(year) + "-" + correctedMonth
+ "-01";
}
if (month < 10) {
correctedMonth = "0" + Integer.toString(month);
} else correctedMonth = Integer.toString(month);
firstDay = Integer.toString(year) + "-" + correctedMonth + "-01";
firstDay = "2012-02-25";
Cursor mCursor =
mDb.query(DATABASE_TABLE_EVENTS, new String[] { KEY_EID, KEY_ENAME,
KEY_EINTERESTS, KEY_EBENS, KEY_EDATE, KEY_ETIME, KEY_EVHO, KEY_EABBR,
KEY_ELOCATION, KEY_ETYPE, KEY_ENATURE, KEY_ESTATUS,
KEY_ESIGNEDUP, KEY_ECAPACITY}, "eventDate >= " + firstDay
// + " AND "eventDate < " + lastDay
, null, null, null,
"eventDate");
if (mCursor != null) mCursor.moveToFirst();
return mCursor;
}
Have you tried to reproduce the query directly? (I mean querying the database with some tools like SQLite Manager).
NB: when you are using STRINGS you have ALWAYS to use single quote!
I also modified it to use selection and selection args, so you are much security safer and it do the job of inserting the single quote automatically. Try it
So your query have to be:
Cursor mCursor =
mDb.query(DATABASE_TABLE_EVENTS, new String[] { KEY_EID, KEY_ENAME,
KEY_EINTERESTS, KEY_EBENS, KEY_EDATE, KEY_ETIME, KEY_EVHO, KEY_EABBR,
KEY_ELOCATION, KEY_ETYPE, KEY_ENATURE, KEY_ESTATUS,
KEY_ESIGNEDUP, KEY_ECAPACITY}, "eventDate >= ? AND eventDate < ?"
, new String[] { firstDay, lastDay}, null, null,
"eventDate");
if (mCursor != null) mCursor.moveToFirst();
Also a really big advice is to never store dates and times with strings. First of all because they are static in this way, instead you have to think that people live in different countries with different times and timezones so you have to think in a worldwide way :)
The best way to store dates and times is (in my opinion) with a long (time stamp).
So when you retrieve a date/time you can pass directly it to a Date constructor or a Calendar constructor. Also it's much, much much easier to compare dates in that way and it's really much faster than String compare :)
You have to format the string date using strfttime() function in SQLite.The different formats is mentioned in the following link.
http://www.sqlite.org/lang_datefunc.html
Hope it helps
try this, here my example is dealing with complete date where you can deal with only month and year
Date filed in the SQLite table will be TEXT and date data should be stored as "2012-12-31 00:12:00" format that comparison dose not give you trouble and if we consider that fields are date_from and date_to and we are storing current date at to_date then we should get the current date as bellow and
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String to_date = sdf.format(new Date());
and the SQL query should be
crs = db.rawQuery(
"SELECT _id, date_from, date_to, done_or_not, list_name " +
"FROM list_tbl " +
"WHERE " +
"date_from <= Datetime('"+to_date+"') AND date_to >= Datetime('"+to_date+"')", null);