views:

393

answers:

4

Hi, i use core data in my iphone app, but in some case i use sqlite to access to data and ia have a problem with NSDate.

NSDate *now = [NSDate date];
     NSCalendar *calender = [NSCalendar currentCalendar];;
     NSDateComponents *comp = [calender components:NSYearCalendarUnit fromDate:now];
     [comp setDay:1];
     [comp setMonth:1];
     NSDate *yearAgo = [calender dateFromComponents:comp];
     NSPredicate *predicate = [NSPredicate predicateWithFormat:@"date > %@",yearAgo];

This code works and select records from the start of year, but if i use sqlite raw query

NSDate *current=[NSDate date];
      NSDateComponents *comps = [gregorian components:(NSDayCalendarUnit | NSMonthCalendarUnit |NSYearCalendarUnit) fromDate:current];
      [comps setDay:1];
      [comps setMonth:1];

      NSDate *yearDate = [gregorian dateFromComponents:comps];

      [where appendFormat:@"zdate > '%@' ",yearDate];

I have a problem, wrong date determined by the records, Records that in core date has date like 2008-01-01 in sqlite have dates like 1977 year. How to fix it? May be I was wrong to use NSDate in the query?

+1  A: 

I haven't checked this, but off the top of my head I'd guess that sqlite expects a different date format. Consider using an NSDateFormatter to convert it to the one sqlite uses.

Ian Henry
NSDate uses the format "YYYY-MM-DD HH:MM:SS ±HHMM"; SQLite accepts "YYYY-MM-DD HH:MM:SS", among others. I don't think the time zone will have an affect unless the date and time are the same, though the fact that all dates in SQLite are in UTC means that they can't properly be compared to local NSDates (unless you live in GMT).
outis
To clarify: the different formats won't have an effect for the OP's query. In general, it will have an effect in that an NSDate and SQLite date will never compare equal.
outis
A: 

Wrong usage of NSDate in predicate!

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"date > %@",yearAgo]; - worng

I must use this:

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"date > '%f'",[yearAgo timeIntervalSinceReferenceDate];

And all works.

Sergey Zenchenko
No, it doesn't. It may look like it is working but I am 100% sure you have a float version of the pointer to your NSDate object!!!
Kendall Helmstetter Gelner
No, I think this is correct. -timeIntervalSinceReferenceDate returns an NSTimeInterval, which is typedef'd to double, so he is getting a proper floating point number. If the date is stored in the database as a floating point timestamp, this should work.
Brad Larson
A: 

In some cases you'll need to add 31 years to the dates in the SQLite DB.

From the book: IPhone Forensics: Recovering Evidence, Personal Data, and Corporate Assets By Jonathan Zdziarski On calendar events:

Unlike most timestamps used on the iPhone, which are standard Unix time-stamps, the timestamp used here is an RFC 822 timestamp representing the date offset to 1977. To convert this date, determine the actual RFC 822 time-stamp and add 31 years.

dtroy
+2  A: 

For doing any query or other SQLLite operation, you should always (always!!!) use bind variables. So the query would look like:

zdate > ?

Then you make a prepared statement, bind the date variable, and execute the statement to get your results.

Kendall Helmstetter Gelner