FMDB queries with NSDate execute but do not take effect - iphone

Any query I execute through FMDB that include NSDates execute but do not return result sets or make edits to the database. I am working in the ios 4.3 simulator.Other Queries that do not stipulate a date execute correctly. Heres an exerpt of the code that i use:
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc]init];
[dateFormatter setDateFormat:#"yyyy-MM-dd hh-mm-ss"];
NSDate *start = [dateFormatter dateFromString:#"2011-07-18 06:40:21" ];
NSDate *end = [dateFormatter dateFromString:#"2011-07-18 06:41:19"];
[dateFormatter release];
FMDatabase* db = [FMDatabase databaseWithPath:appDelegate.databasePath];
if (![db open]) {
NSLog(#"Could not open db.");
}
[db beginTransaction];
[db executeUpdate:#"delete from time_stamp_table where time_stamp >= ?
and time_stamp <= ?",start,end];
NSLog(#"Err %d: %#", [db lastErrorCode], [db lastErrorMessage]);
[db commit];
[db close];
The schema states time_stamp in the time_stamped_table thusly:
create table time_stamp_table{
id INTEGER PRIMARY KEY,
time_stamp DATETIME NOT NULL
}
When I make these queries in sqlite3 on the command line, using the database stored on the simulated Application context, they work. Is there some special preperation for querying by NSDate with FMDB that I am missing?

Query like
SELECT * from Time_Stamp where updatedTime >= DATE('2011-05-17 06:40:21') AND updatedTime <= DATE('2011-07-19 06:40:21')
fetches the correct records while comparing the dates. You might take some hint from this and change your query something like
[db executeUpdate:#"delete from time_stamp_table where time_stamp >= DATE(?)
and time_stamp <= DATE(?)",start,end];
or
[db executeQuery:[NSString stringwithFormat:#"delete from time_stamp_table where time_stamp >= DATE('%#')
and time_stamp <= DATE('%#')",start,end];
I have not tested the queries so You will have to test it yourself. Hope it helps

Try to avoid parsing a NSDate to a SQL-Query. Rather try parsing a NSString in a format sqlite may understand: '2011-07-18 06:41:19'.
If you would like sqlite to compare the values you have to use the a specific date function. Sqlite3 provides you the DATE, TIME or DATETIME functions to convert your strings.
Secondly, to correct Rahul Sharma, using the DATE function to compare a TIMESTAMP would fail because TIMESTAMP is saving both date and time. Therefore the DATETIME function should be used.
[db executeUpdate:#"delete from time_stamp_table where time_stamp >= DATETIME(?)
and time_stamp <= DATETIME(?);",
#"2011-07-18 06:40:21",
#"2011-07-18 06:41:19"];

May be you have used executeQuery method. Delete operation belongs to updating operation. At first, I've used executeQuery, but couldn't find the problem even checking the property type once and once again. Finally executeUpdate fixes it.

Related

calculating timestamp in iOS for core data project

I am using core data in my project. Database is sqlite and there is column for storing "birthdate" having datatype "timestamp".
Now, I want to insert some records in it and I am having dates in human readable format like "1809-06-17".
How to convert this date to timestamp so that, I get this date when fetched from database.
I tried some conversions using python script, but I got different results.
Is there any easy way to do this? Please help me.
You could store the date as TEXT and dont have to worry about converting to and from timestamp.
To convert timestamp to NSDate use:
NSDate *date = [NSDate dateWithTimeIntervalSince1970:timeStamp];
NSLog(#"%#", date);
String to NSDate to timestamp:
NSDate *date = [NSDate dateWithString:stringWithDate];
NSTimeInterval timeStamp = [date timeIntervalSince1970];
SQLite doesnt have a datatype for Date, it just stores it in a INT (Unix Time), REAL(Julian day numbers) or TEXT(ISO8601 strings) depending on what you choose.
So you could just store the date in the format you already have ("1809-06-17") as a TEXT column or you store as a timestamp in an INT column using the methods above to convert both ways.
SQLite Date and Time functions: SQLite date and time
SQLite DATATYPES: SQLite datatypes doc
SQLite Oficial Site and Documentation: SQLite Home
Hope you can solve your problem
Finally I got the solution I needed.
NSDateFormatter *df = [[NSDateFormatter alloc]init];
[df setDateFormat:#"yyyy-MM-dd"];
NSDate * past = [df dateFromString:#"1971-04-06"];
NSTimeInterval oldTime = [past timeIntervalSinceDate:[df dateFromString:#"2001-01-01"]];
NSString * unixTime = [[NSString alloc] initWithFormat:#"%0.0f", oldTime];
NSLog(#"unixTime = %#",unixTime);

FMDB how can I query data from date range on Sqlite iPhone dev

I am trying to perform a query on a table where there is a date field and I want to query over a range of values The where clause looks like the following:
[db executeQuery:#"select * from test where myDate BETWEEN date('now','-7 days') and date('now')"];
But it doesn't seem to work :(
If you used DATETIME column with table declaration, you can do this:
[db executeQuery:#"SELECT * FROM test WHERE myDate BETWEEN ? and ?", [[NSDate dateWithTimeInterval:-86400*7 sinceDate:[NSDate date]], [NSDate date]];
Note that -86400 is seconds of a day, negative indicates "days before" like your question.
Also note that BETWEEN syntax includes the very second of the date you set. Use WHERE myDate > ? and myDate < ? if you need non-inclusive match.

Storing NSDate with system time zone in Core Data

When I store a date in CoreData as [NSDate date], it is saved -5:30 difference. In core data I used attribute type as date.
How to store NSdate with timeZone?
Update: Here is the code I am using:
To store the date:
database = (DataBase*) [fetchResults objectAtIndex:indexVal];
[database setDate:[NSDate date]];
NSError error = nil;
[managedObjectContext save:&error]
To retrieve the date:
DataBase *newDataBase = (DataBase) [fetchResults objectAtIndex:i];
NSDate *RetrivedDate = [newDataBase Date];
NSLog(#"Retrived Date :",RetrivedDate");
Before storing I log it. It shows current date and time. After storing I immediately fetched the date . but it showed 1 day delayed date..
NSDate doesn't have a time zone. It stores dates as a number of seconds since a reference date in GMT.
The time zone is applied when you format the date for display using NSDateFormatter. This will pick up the device time zone by default.

iPhone SQLite date problem

Database gets created just fine, and the insert works just fine. I'm having problem with the select statement below. It returns no records and no error. A select on any other field works just fine. Can anyone spot what I'm doing wrong?
"create table if not exists data (pkey integer primary key, doc date)"
[db executeUpdate:#"insert into data ( doc) values (?)" , [NSDate date]];
"select * FROM data WHERE doc between '2009-08-23' and '2009-08-23' "
The part between '2009-08-23' and '2009-08-23' is always false, because that's a range of zero time, for lack of a better description.
If you want items occurring on exactly 2009-08-23, select between '2009-08-23' and '2009-08-24' which will range from midnight on the 23rd to midnight on the 24th.
Here's an example of this in action:
sqlite> CREATE TABLE t (d DATETIME);
sqlite> SELECT DATETIME('now');
2009-08-24 02:32:20
sqlite> INSERT INTO t VALUES (datetime('now'));
sqlite> SELECT * FROM t;
2009-08-24 02:33:42
sqlite> SELECT * FROM t where d BETWEEN '2009-08-24' and '2009-08-24';
sqlite> SELECT * FROM t where d BETWEEN '2009-08-24' and '2009-08-25';
2009-08-24 02:33:42
I have had to do this exact type of lookup on sqlite and here is a simple date formatting example to get the start and end of day timestamps for your date.
In my case I am storing the timestamps with this timestamp format in sqlite: "yyyy-MM-dd HH:mm:ss.SSSS". This example uses the current date ([NSDate date]).
NSDateFormatter *dateFormatter = [[[NSDateFormatter alloc] init] autorelease];
[dateFormatter setDateFormat:#"yyyy-MM-dd"];
NSString *dateString = [dateFormatter stringFromDate:[NSDate date]];
NSDate *startOfDay = [dateFormatter dateFromString:dateString];
// add a full day and subtract 1 second to get the end of day timestamp
NSDate *endOfDay = [startOfDay addTimeInterval:(60*60*24)-1];
[dateFormatter setDateFormat:#"yyyy-MM-dd HH:mm:ss.SSSS"];
You can then use startOfDay and endOfDay for your query values.
SQLite does string comparison, not date comparison.
So, one way to solve your problem is:
"select * FROM data WHERE doc between '2009-08-23' and '2009-08-23 99' "

sqlite datetime data type with iphone NSdate?

Is there a way in sqlite to automatically save a timestamp in the table whenever a record has been created that I can then grab and save as an NSDate in my application?
Or should I instead create the NSdate object with the current time in my iphone app, and then insert it into the database. If so? What column should the datatype be for the time? a DATETIME?
What I do is use sqlite's current_timestamp (which looks something like this: 2009-06-16 12:11:24). To do this just set the row type of your qslite table to
Data type: "DATETIME"
Allow null: NO
Default value: CURRENT_TIMESTAMP
Then use an SQL query like this:
#"INSERT INTO 'scores' ('one', 'two', 'three') VALUES ('%d', '%d', '%d')"
ignoring the date, so that it will automatically get the current time value.
Then to convert this to an NSDate you can use an NSDateFormatter like this:
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:#"yyyy-MM-dd HH:mm:ss"]; //this is the sqlite's format
NSDate *date = [formatter dateFromString:score.datetime];
and now you have that date as an NSDate object. Just don't forget to release the NSDateFormatter we allocated :)
There is no TIMESTAMP datatype that you can use in SQLite, so you'll have to manually insert the time when you do your INSERT. I use the INTEGER datatype in the database, and convert my NSDate as such:
sqlite3_bind_double(insert_statement, 1, [myDate timeIntervalSince1970]);
And to get it back out of the DB:
myDate = [NSDate dateWithTimeIntervalSince1970:sqlite3_column_double(select_statement, 1)];
I like to use the sqlite julianday() function, like:
insert into foo(currentDate) values (julianday('now'));
This would be inserting a floating point value into foo.currentDate.
You might also find some details of this question/answer useful.
How get a datetime column in SQLite with Objective C