I'll show you the code first
#Query("SELECT * FROM plan WHERE (DATETIME(startDate, '%Y-%m-%d') <= :temp OR DATETIME(endDate, '%Y-%m-%d') >= :temp) OR specificDate = :temp")
fun getPlanByDate(temp: String): List<PlannerEntity>
Inside the table named plan, there are startDate, endDate, and specificDate columns. Based on the date called temp, I want to get only data belonging to temp. The format of temp is "yyyy-MM-dd". The startDate and endDate are stored in "yyyy-MM-dd HH:mm" format, so you can see my efforts to change it to "yyyy-MM-dd" format. How can I change the format yyyy-MM-dd HH:mm to yyyy-MM-dd format?
How can I change the format yyyy-MM-dd HH:mm to yyyy-MM-dd format?
Use date(the_column) or strftime('%Y-%m-%d',the_column)
However, I believe that your logic is incorrect as it will only be if the endDate is less than the startDate that a row will be excluded.
You possibly want AND rather than OR as per :-
.... WHERE (date(startDate) <= :temp AND date(endDate) >= :temp) OR date(specificDate) = :temp
or alternately the simpler :-
.... WHERE :temp BETWEEN date(startDate) AND date(endDate) OR date(specificDate) = :temp
You may wish to refer to SQLite Date And Time Functions from which covers the date, datetime, time, julianday and strftime functions (i.e. date manipulation).
Android SQLiteStatement: how to bind numeric (Date, BigDecimal)?
SQLiteStatement has
bindNull
bindLong
bindDouble
bindString
bindBlob
For java.util.Date and java.util.BigDecimal, they are mapped to Numeric as column type. But there is no bindNumeric(...) method. Which method for binding these types?
Date
Date could be bound as long or a String depending on the value. The former if it's an integer representation of the date, the latter if it's a more human readable date. It may be wise to use the formats supported by SQLite's Date/Time functions as per :-
Time Strings
A time string can be in any of the following formats:
YYYY-MM-DD
YYYY-MM-DD HH:MM
YYYY-MM-DD HH:MM:SS
YYYY-MM-DD HH:MM:SS.SSS
YYYY-MM-DDTHH:MM
YYYY-MM-DDTHH:MM:SS
YYYY-MM-DDTHH:MM:SS.SSS
HH:MM HH:MM:SS
HH:MM:SS.SSS
now
DDDDDDDDDD
Date And Time Functions
Big Decimal
You can downgrade to double and bind as a double (noting potential loss), bind as a string (note type affinity comes into play i.e. column affinity should be TEXT) or use two longs one for the scale and one for the un-scaled value.
You should refer to Datatypes In SQLite Version 3
I am running sqlite to select data between two ranges for a sales report. To select the data from between two dates I use the following statement:
SELECT * FROM test WHERE date BETWEEN "11/1/2011" AND "11/8/2011";
This statement grabs all the dates even those outside the criteria. The date format you see entered is in the same format that I get back. I'm not sure what's wrong.
SQLite requires dates to be in YYYY-MM-DD format. Since the data in your database and the string in your query isn't in that format, it is probably treating your "dates" as strings.
Change your data to that formats to use sqlite datetime formats.
YYYY-MM-DD
YYYY-MM-DD HH:MM
YYYY-MM-DD HH:MM:SS
YYYY-MM-DD HH:MM:SS.SSS
YYYY-MM-DDTHH:MM
YYYY-MM-DDTHH:MM:SS
YYYY-MM-DDTHH:MM:SS.SSS
HH:MM
HH:MM:SS
HH:MM:SS.SSS
now
DDDDDDDDDD
SELECT * FROM test WHERE date BETWEEN '2011-01-11' AND '2011-08-11'
One more way to select between dates in SQLite is to use the powerful strftime function:
SELECT * FROM test WHERE strftime('%Y-%m-%d', date) BETWEEN "11-01-2011" AND "11-08-2011"
These are equivalent according to https://sqlite.org/lang_datefunc.html:
date(...)
strftime('%Y-%m-%d', ...)
but if you want more choice, you have it.
SELECT *
FROM TableName
WHERE julianday(substr(date,7)||'-'||substr(date,4,2)||'-'||substr(date,1,2)) BETWEEN julianday('2011-01-11') AND julianday('2011-08-11')
Note that I use the format: dd/mm/yyyy.
If you use d/m/yyyy, Change in substr().
Or you can cast your string to Date format with date function. Even the date is stored as TEXT in the DB.
Like this (the most workable variant):
SELECT * FROM test WHERE date(date)
BETWEEN date('2011-01-11') AND date('2011-08-11')
SQLite does not have a concept of dates. It only knows them as text. When you do this in SQLite you're actually doing string comparisons. You can read more from the official documentation.
When two TEXT values are compared an appropriate collating sequence is used to determine the result.
Any numeric (i.e., not using words like 'May') format for dates that is padded and in order from biggest field to smallest field will work. "2021-05-07" (May 7th) comes before "2021-05-09" (May 9th). So if you use "yyyy-mm-dd" format then you'll be set. "yyyy/mm/dd" and "yyyymmdd" work just fine too. (For a better phrasing on "sortable" date formats check out RFC 3339 section 5.1.)
A reason to use "yyyy-mm-dd" format is because that's the format that SQLite's builtin date uses.
Special thanks to Jeff and vapcguy your interactivity is really encouraging.
Here is a more complex statement that is useful when the length between '/' is unknown::
SELECT * FROM tableName
WHERE julianday(
substr(substr(date, instr(date, '/')+1), instr(substr(date, instr(date, '/')+1), '/')+1)
||'-'||
case when length(
substr(date, instr(date, '/')+1, instr(substr(date, instr(date, '/')+1),'/')-1)
)=2
then
substr(date, instr(date, '/')+1, instr(substr(date, instr(date, '/')+1), '/')-1)
else
'0'||substr(date, instr(date, '/')+1, instr(substr(date, instr(date, '/')+1), '/')-1)
end
||'-'||
case when length(substr(date,1, instr(date, '/')-1 )) =2
then substr(date,1, instr(date, '/')-1 )
else
'0'||substr(date,1, instr(date, '/')-1 )
end
) BETWEEN julianday('2015-03-14') AND julianday('2015-03-16')
Put the variable in the Where Condition and parse both dates using 'BETWEEN':
SELECT * FROM emp_master
-> if you have date formate like dd/mm/yyyy simple then,
WHERE joined_date BETWEEN '01/03/2021' AND '01/09/2021';
-> and if you have date formate like yyyy/mm/dd then,
WHERE joined_date BETWEEN '2021/03/01' AND '2021/09/01';
☻♥ Done Keep Code.
Let's say you are preparing data for some report. Then the whole ordeal will look similar to this.
--add column with date in ISO 8601
ALTER TABLE sometable ADD COLUMN DateInISO8601;
--update the date from US date to ISO8601 date
UPDATE sometable
SET DateInISO8601 = substr([DateInUSformat],length([DateInUSformat])+1, -4)
|| '-' ||
substr('00' || [DateInUSformat],instr('00' || [DateInUSformat],'/'),-2)
|| '-' ||
substr('00' || rtrim(substr([DateInUSformat],instr([DateInUSformat],'/')+1,2),'/'),-2,2);
SELECT DateInISO8601
FROM sometable
WHERE DateInISO8601 BETWEEN '2022-02-02' AND '2022-02-22';
You can of course do all that on the fly, but if you have the choice -- don't. Use the ISO date by default and convert it on the way in and out to SQLite DB.
I as having time in hh:mm aa format ex: 01:30 AM.
While creating table I am specifying the datatype as TIME. But there is no way of setting its format. By default it is HH:MM:SS format. So while entering AM/PM values it is not added in database.
Is there a way to store my time in my required format using TIME datatype column so that sorting can be done easier.
Also I tried saving the time as TEXT datatype. I order it by taking substirng of AM/PM and do string sorting. The problem in it is 12:30 PM will be not correctly ordered.
ex: 12.30 PM, 12.30 AM, 02.30 PM will be ordered as 12.30 AM,02.30 PM,12.30 PM
How can I order this column and what datatype can I give for this?
Use hh:mm:ss for storing values in the database.
(It's required for correct sorting, and by all built-in time functions.)
Use the hh:mm aa format (or any other format) for displaying values.
You cannot forsee what format is the default for your user's locale, or if the user has selected another time format, so you must be prepared to format times for displaying them in any case.
In my project i stored the dates in the dateadded filed like below.
01-07-14 12:00
02-07-14 12:00
25-06-14 13.00
When i fire query for minimum date:
Select dateadded from dgadata order by dateadded asc limit 1
That is return 01-07-14 12:00 and even if i write Select min(dateadded) from dgadata the output is same. But here the minimum date is 26-06-14 13.00
And in the max date i write like
Select dateadded from dgadata order by dateadded desc limit 1
Here the result is 25-06-14 13.00 but here the max date is 02-07-14 12:00
I think my query is fine i don't know why i am getting wrong result.
SQLite doesn't have dedicated datetime types, but does have a few datetime functions. Follow the string representation formats (actually only formats 1-10) understood by those functions (storing the value as a string) and then you can use them, plus lexicographical comparison on the strings will match datetime comparison (as long as you don't try to compare dates to times or datetimes to times, which doesn't make a whole lot of sense anyway).
Depending on which language you use, you can even get automatic conversion. (Which doesn't apply to comparisons in SQL statements like the example, but will make your life easier.)
The reason is because the comparison is performed in the stored string. I think that this may help.
For what I can see, it seems that you have defined your dateadded field as TEXT, you should store a timestamp (integer) value instead of a text value, this way it will be easy to order them.
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.`
Another possible solution is to store your dates as YYYMMMDDHHMMSS, this way your order by will work aswell.