I'm attempting to store 3 values in a database I've created on an android device. The values are NAME, DATE, and TIME. My question is thus: what is the best approach to fetch and store the current DATE and TIME values when they are inserted into the database?
So far I have identified two ways to do this, either by making system calls in android like //values.put(TIME, System.currentTimeMillis()); or using SQL functions like GETDATE(). But, which is better?
If I'm heading off in the wrong direction, please let me know and direct me towards the right direction.
Using the SQL functions will be more compatible with other tools using the same SQL engine.
Using text in ISO format YYYY-MM-DD hh:mm:ss.fff will be widely compatible and still sort properly.
The sqlite docs give these column type options for storing dates:
TEXT as ISO8601 strings ("YYYY-MM-DD HH:MM:SS.SSS").
REAL as Julian day numbers, the number of days since noon in Greenwich on November 24, 4714 B.C. according to the proleptic Gregorian calendar.
INTEGER as Unix Time, the number of seconds since 1970-01-01 00:00:00 UTC.
You could use TEXT as described by Doug Currie, or you could use INTEGER using a java.util.Date. (I don't know why you'd use the REAL option.)
To use INTEGER, you could load and store dates something like this:
// build a date from a Cursor
Date d = new Date(cursor.getLong(DATE_FIELD_INDEX));
// add a date to an SQLiteDatabase
final ContentValues values = new ContentValues();
values.put(DATE_FIELD, d.getTime());
db.insert(TABLE_NAME, null, values);
This will be less readable in your database, but comparisons between dates (in your query) should be faster since comparing numbers is faster than strings. (Although I don't know much about the sqlite implementation.)
Related
I have a database that contains upcoming births. The file has 5 records in it with due dates of (11-15-2016,10-15-2016, 12-14-2016, 12-13-2016 and 02-12-2017)
The query is
SQLiteDatabase db = dbhelper.getReadableDatabase();
String QueryPart1="SELECT inseminations._ID, inseminations.patient_id, inseminations.date_due ";
String QueryPart2="FROM inseminations ";
String QueryPart3="WHERE inseminations.date_due>=? ";
String QueryPart4="ORDER BY inseminations.date_due ASC";
String FinalQuery=QueryPart1+QueryPart2+QueryPart3+QueryPart4;
mCursor = db.rawQuery(FinalQuery ,howToFilter);'
howToFilter is
String howToFilter[]={ExpectedDateDue};
ExpectedDateDue is
ExpectedDateDue = new SimpleDateFormat("MM-dd-yyyy").format(new Date());
The query retrieves all records except for the one from 2017, the listview is sorted correctly, it's as if the query is only taking those records where the month is after the current month instead of the entire date.
Comparison operators on text in SQLite use lexicographic order. What this means, for example, is "01-01-2017" is less than "05-04-2016". SQLite has no indication that these strings represent moments in time that should be compared chronologically.
In general, I dislike using strings for timestamps in my databases for reasons like this. I much prefer to store timestamps as long values representing seconds (or milliseconds) since epoch. It's far easier to compare timestamps this way, and converting to and from date strings is simple enough either in SQLite or in Java.
If that's not feasible for some reason, then I suggest you alter the way you store your date strings in the database. Instead of MM-dd-yyyy, use yyyy-MM-dd. In this format, lexicographic comparisons will work; using the same example as before, "2017-01-01" is greater than "2016-05-04". Additionally, this format is acceptable as input to SQLite's various date and time functions, should you decide to use them.
If you can't alter the way the dates are stored, you will need to somehow convert them into a format that is comparable in the way you expect. You could use SQLite's substr() and || (concatenation) functions in the query to convert the date from MM-dd-yyyy to yyyy-MM-dd format. The code in this answer demonstrates this.
I am trying to create a simple reminder app. Im just logically thinking about the process. Basically I want to be able to choose a DAY and time e.g Monday 15:00, this will trigger EVERY Monday 15:00 until it gets deleted from database. Having said that example I have questions to accomplish this process.
How will I store DAY and TIME, what type, do I need different columns in my table?
How can I compare real time DAY to current DAY, so if its Monday real time it will return ONLY Monday reminders? is this possible?
Will I need to primarly focus using calendar?
As documentation says:
SQLite does not have a storage class set aside for storing dates
and/or times. Instead, the built-in Date And Time Functions of SQLite are capable of storing dates and times as TEXT, REAL, or INTEGER values.
You can store date and time in the TEXT type of field in the following format:
YYYY-MM-DD HH:MM:SS.SSS
and then use built-in date & time functions of SQLite to filter your records.
Another option is to store date & time as a time-stamp in milliseconds and write proper queries for selecting data or use Joda library for filtering or date & time transformation, but probably such solution would be less efficient and less convenient than first option.
Using integer column is the easiest solution.
Just store the date in millisecond (Calendar.getTimeInMillis()) and your good to go.
Then you just have to search on that integer to find the correct event in your database :
String selectQuery = "SELECT whateveryouneed FROM events WHERE date_event > ?";
Cursor c = db.rawQuery(selectQuery, new String[] { String.valueOf(calendar.getTimeInMillis())});
...
if you need to find all the event for a day , you just have to find the limits of the day in millisecond and make a query according to those limits
Hi i need to do a query where I compare 2 dates and select all the objects created between those 2 dates.
My date field is a Text type.
I have run some tests and apparently the date is being stored in YYYY-MM-DD format.
Im using this code to do the query:
return bd.query("Gasto", null , "Fecha_Creado between '"+fecha1+ "' and '"+fecha2+"'", null, null, null, "Fecha_Creado DESC", null);
and this code to retrieve the dates and pass them to the previous function
return bd.obtenerGastosVar(fecha.get(Calendar.YEAR)+"-"+(fecha.get(Calendar.MONTH)+1)+"-1",
fecha.get(Calendar.YEAR)+"-"+(fecha.get(Calendar.MONTH)+1)+"-"+fecha.getActualMaximum(Calendar.DAY_OF_MONTH), ordenadoPor);
so the final result should a query that is saying :
select * from gasto where date between date1 and date2
so thats
select * from gasto where date between 2013-8-1 and 2013-8-31
so, that query is supposedly making a date comparison with the former YYYY-MM-DD.
Im expecting objects created between those two dates, but its NOT working. Its was working an hour ago
I did something funny and use for the query dates, a DD-MM-YYYY format. And that apparently is working, but im scared that using this format for the queries will bring not reliable results.
So how can I fix this and still get reliable results?
Thanks for your help
Apparently, for me to be able to compare the dates, achieving good results, dates must have 2 digits months and days
for example 2013-04-09 or 2013-11-25
dates with one digit months or days don't work
I have this query which works in SQL server:
Convert(datetime, [ChangedDate]) >= DATEADD(DAY, -3, CAST(GETDATE() AS DATE))
I want to make it work in Android SQLite database.
As far as I understood I need to use something like: date('now','+14 day') instead of DATEADD, but it gives me an error on datetime (it could be here Convert(datetime,...) in sqlite.
Can you modify this query in order to make it works on SQLite?
SQLite does not have a date data type. So you're not required to use convert or cast. A query like this would work:
select *
from table1
where col1 < datetime('now', '-3 days')
Example at SQL Fiddle.
For more details, see the SQLite manual:
1.2 Date and Time Datatype
SQLite does not have a storage class set aside for storing dates
and/or times. Instead, the built-in Date And Time Functions of SQLite
are capable of storing dates and times as TEXT, REAL, or INTEGER
values:
TEXT as ISO8601 strings ("YYYY-MM-DD HH:MM:SS.SSS").
REAL as Julian
day numbers, the number of days since noon in Greenwich on November
24, 4714 B.C. according to the proleptic Gregorian calendar.
INTEGER
as Unix Time, the number of seconds since 1970-01-01 00:00:00 UTC.
Applications can chose to store dates and times in any of these
formats and freely convert between formats using the built-in date and
time functions.
I am using SQLite database for my application.
The Table Structure Goes Like :
_id : integer primary key
name : text
day : date
I am able to store date in format : dd-mmmmm-yyyy eg. 15-June-2011
But when i tried to retrieve all records filtered by date from the database it returns me null.
database.query(DATABASE_TABLE, new String[] { "strftime('%d-%mm-%Y',date('now'))","strftime('%d-%m-%Y',"+KEY_DAY+")" },
"strftime('%d-%m-%Y',date('now'))=" + KEY_DAY , null,null,null,null,null);
It didnt match with anyrow's date even though there were some matching dates.
I have already gone thru documentation of SQLite. But didn find any solution yet.
I want to have something like :
select * from table where day=curdate();
How can i do the same task in SQLite ?.
(Yes I am flexible to change the format of date stored in Dateabase)
What are other alternatives for the same task ?.
In java programming you can convert any date format into long (time in milliseconds) and viceversa. My opinion is while storing format the date into long format in java and then store long value of date in database. also while retrieving you can retrieve the long value and then format that as per your expected date format. I have been using this type of logic for several application.
Thanks
Deepak.
The function strftime('%d-%m-%Y',date('now')) returns a string with the month in numeric format (from 01 to 12). As far as I can tell from the docs, there is no format specifier to return the full name of the month.
I think you'll have to store your dates using numerical month specifiers instead of names.