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
Related
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).
I have a requirement, wherein column having date time information must be compared against present date & time. If earlier then this particular record must be deleted.
I have progressed with below implementation, but not getting any error & expected behavior is not met.
SimpleDateFormat dateFormat = new SimpleDateFormat("dd MMM yyyy HH:mm", Locale.getDefault());
Calendar nowCalendar = Calendar.getInstance();
String strNowTime = dateFormat.format(nowCalendar.getTime());
// Delete the records at Manager_Dashboard SQLiteDB
String whereClause = "DATETIME(End_Time) < DATETIME(?)";
String whereArgs[] = {strNowTime};
dbOfflineRange.delete("Offline_Range",whereClause,whereArgs);
As you could notice, if I have a record with End_Time in text within SQLite table (as 30 Nov 2018 21:35), then this should be compared against current datetime (as 30 Nov 2018 23:35)
As End_Time being earlier than Now, I am expecting deletion. But its not happening.
The Date and Time SQL functions require the date to be in a recognised format.
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
SQL As Understood By SQLite - Date And Time Functions
Your best(simplest) option would be to store them as YYYY-MM-DD HH:MM (i.e. change the SimpleDateFormat accordingly).
Note you would not even need the datetime function as direct comparison of the values would result in the desired outcome.
Storing the unix timestamp value would be the more efficient storage/processing time wise.
You can then use the strftime function to return the date in the format you wish.
Otherwise you can convert the store value to a recognised format using SQL functions such as substr and then do the comparison.
SQL As Understood By SQLite - Core Functions
here's an example of how you could handle data stored in DD MMM YYYY HH:MM format
assuming that the value to compare against is provided in YYYYMMDDHH:MM format :-
DROP TABLE IF EXISTS Offline_Range;
CREATE TABLE IF NOT EXISTS Offline_Range (end_time);
-- Add some test data dd MMM yyyy HH:mm
INSERT INTO Offline_Range VALUES
('21 May 2018 10:30'),
('21 Jun 2018 10:30'),
('21 Jul 2018 10:30'),
('21 Aug 2018 10:30')
;
SELECT * FROM Offline_Range
WHERE
substr(end_time,8,4)||
CASE
WHEN instr(end_time,'Jan') THEN '01'
WHEN instr(end_time,'Feb') THEN '02'
WHEN instr(end_time,'Mar') THEN '03'
WHEN instr(end_time,'Apr') THEN '04'
WHEN instr(end_time,'May') THEN '05'
WHEN instr(end_time,'Jun') THEN '06'
WHEN instr(end_time,'Jul') THEN '07'
WHEN instr(end_time,'Aug') THEN '08'
WHEN instr(end_time,'Sep') THEN '09'
WHEN instr(end_time,'Oct') THEN '10'
WHEN instr(end_time,'Nov') THEN '11'
WHEN instr(end_time,'Dec') THEN '12'
END
||
substr(end_time,1,2)||substr(14,5)
<
'2018062200:00' -- 22 Jun 2018 00:00 amended to suit i.e. the value input
This creates a table :-
The result from the query would be :-
I am comparing time in android sqlite database, here is my table structure in the screen shots. Actually I have two times, like 8:00 and 7:30 (basically these are employee shift timings) in the string and I have a column c_TIME in my database and I want all the records who lies in b/w my two time i.e.(8:00 and 7:30) from c_TIME.
I have used this query but it is not working, please anyone guide me what I am doing wrong
SELECT *
FROM ATTENDANCE
WHERE strftime('%H','08:00') > strftime('%H', c_TIME) AND
time('08:00') < strftime('%H', c_TIME) AND
STATE = 'IN'
The following should work:
SELECT *
FROM ATTENDANCE
WHERE strftime('%H:%M:%S', c_date) > '07:30:00' AND
strftime('%H:%M:%S', c_date) < '08:00:00' AND
STATE = 'IN'
Comments:
Instead of using the c_TIME field, you should use c_date. Actually, I don't see any value in keeping around a column which stores the time separately.
strftime returns a string based on some sort of datetime/timestamp input. The output from strftime('%H:%M:%S', c_date) should have the form HH:MM:SS, and this string can be compared lexicographically against 08:00:00 and 07:30:00. The comparison should still work, because for strings of the same length it should still sort numerically.
Try:
select * from ATTENDANCE where c_date between 'yyyy-mm-dd' and 'yyyy-mm-dd';
Instead of using c_TIME,use c_date field.
You can change the date format in the query accordingly to retrieve data between two specific times.
Sqlite supports 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
See here
I'm running ORMlite on Android app. I have created a #DatabaseTable class with a Timestamp field.
#DatabaseTable
public class Cliente {
#DatabaseField
private Timestamp dateinicio;
}
I can insert items but when I try to recover data I get this error:
java.sql.SQLException: Could not assign object 'Wed Jan 29 13:35:01 CET 2014'
to field FieldType:name=dateinicio,class=Cliente
I suppose this must be a typical error but I cannot resolve it.
Is this existing data you are trying to get to work or did ORMLite store this date for you? Either way you are going to have to match the formats that Sqlite supports.
Internally ORMLite uses "yyyy-MM-dd HH:mm:ss.SSSSSS". You can specify the format using something like the following where the ... is replaced with the format which matches your data.
#DatabaseField(format = "...")
private Timestamp dateinicio;
Sqlite officially supports the following date 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
See this answer here: ORMLite query date format issue
In my appliaction I have to store current date into the database. How can i get the current date and is there is any specific format to store date in database.
Better would be to store the date/time in long in Database and then fetch the long date/time from Database and specify the required format using SimpleDateFormat.
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.
Now for how to insert date in after it.
Use PreparedStatement#setString() or #setLong() respectively.
Hope this explanation works for you..
first convert the date to be stored to a String object using SimpleDateFormat class
code sample:
Date dateToBeStored = new Date();
SimpleDateFormat formatter = new SimpleDateFormat("yyyy/MM/dd"); // this format will help you to convert date to 2012/07/04 format string
String dateString = formatter.format(dateToBeStored); // convert string
now read the date string from DB. you should have some means to get the date back from DB.
String readDateStringFromDB = readDate();
Now parse the read date string to date object by parse method of SimpleDateFormat class
Date dateObj = formatter.parse(readDateStringFromDB); // now you have the Date object back
SimpleDateFormat sdfDateTime = new SimpleDateFormat("dd/MM/yyyy"+ "",Locale.US);
String newtime = sdfDateTime.format(new Date(System.currentTimeMillis()));
You can use the Date class to get the epoch time, which could then be stored in the database as an integer. Alternatively you could convert the epoch time to regular time and store it as a date data type.
https://developer.android.com/reference/java/text/SimpleDateFormat