2009-12-07 5 views
0

J'utilise des données de base dans mon application iphone, mais dans certains cas, j'utilise sqlite pour accéder aux données et j'ai un problème avec NSDate.iphone sqlite NSDate bug

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]; 

Ce code fonctionne et les enregistrements de sélection depuis le début de l'année, mais si j'utilise la requête brute sqlite

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]; 

J'ai un problème, une mauvaise date déterminée par les enregistrements, enregistrements que la date de base A une date comme 2008-01-01 en sqlite ont des dates comme 1977 année. Comment le corriger? Peut-être que j'avais tort d'utiliser NSDate dans la requête?

Répondre

1

Je n'ai pas vérifié cela, mais je suppose que sqlite s'attend à un format de date différent. Envisagez d'utiliser un NSDateFormatter pour le convertir en un usage sqlite.

+0

NSDate utilise le format "AAAA-MM-JJ HH: MM: SS ± HHMM"; SQLite accepte "AAAA-MM-JJ HH: MM: SS", entre autres. Je ne pense pas que le fuseau horaire aura un effet sauf si la date et l'heure sont identiques, bien que le fait que toutes les dates dans SQLite soient en UTC signifie qu'elles ne peuvent pas être comparées correctement aux NSDates locales (sauf si vous habitez en GMT). – outis

+0

Pour clarifier: les différents formats n'auront aucun effet sur la requête de l'OP. En général, cela aura un effet dans le sens où une date NSDate et SQLite ne sera jamais comparable. – outis

-1

Mauvaise utilisation de NSDate dans le prédicat!

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

Je dois utiliser:

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

Et tout cela fonctionne.

+0

Non, ce n'est pas le cas. Cela peut sembler fonctionner mais je suis sûr à 100% que vous avez une version flottante du pointeur vers votre objet NSDate !!! –

+0

Non, je pense que c'est correct. -timeIntervalSinceReferenceDate renvoie un NSTimeInterval, qui est typedef'd à doubler, donc il obtient un nombre réel à virgule flottante. Si la date est stockée dans la base de données sous la forme d'un horodatage à virgule flottante, cela devrait fonctionner. –

3

Dans certains cas, vous devrez ajouter 31 ans aux dates dans la base de données SQLite.

Extrait du livre: iPhone Forensics: Preuve Récupération, données personnelles, et l'actif social Par Jonathan Zdziarski Sur les événements de calendrier:

Contrairement à la plupart horodatages utilisés sur le iPhone, qui sont Unix standard horodatage, l'horodatage utilisé ici est un horodatage RFC 822 représentant la date décalée à 1977. Pour convertir cette date, déterminer le RFC réel 822 et ajouter 31 ans.

2

Pour effectuer une requête ou une opération SQLLite, vous devez toujours (toujours !!!) utiliser des variables de liaison. Ainsi, la requête ressemblerait à ceci:

zdate > ? 

Ensuite, vous faites une déclaration préparée, lier la variable de date, et exécutez l'instruction pour obtenir vos résultats.