Obtenir NSDate pour aujourd'hui avec 00:00:00 comme le time

J'écris une catégorie dans Xcode, qui étendrait la class NSDate actuelle. Je veux append deux methods que j'utilise régulièrement et je n'arrive pas à les faire fonctionner correctement.

Actuellement j'ai ce code:

+ (NSDate*) today { NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar]; NSDateComponents *todayComponents = [gregorian components:(NSDayCalendarUnit | NSMonthCalendarUnit | NSYearCalendarUnit) fromDate:[NSDate date]]; NSInteger theDay = [todayComponents day]; NSInteger theMonth = [todayComponents month]; NSInteger theYear = [todayComponents year]; NSDateComponents *components = [[NSDateComponents alloc] init]; [components setDay:theDay]; [components setMonth:theMonth]; [components setYear:theYear]; NSDate* todayDate = [gregorian dateFromComponents:components]; [components release]; [gregorian release]; return todayDate; } 

Je veux qu'il renvoie une date comme celle-ci: "2010-11-03 00:00:00 +01". Mais d'une manière ou d'une autre, le timezone rest buggin, car ce code renvoie "2010-11-02 23:00:00 +0000".

Quelqu'un peut-il me dire comment corriger ce code pour renvoyer la bonne date? Ou puis-je simplement utiliser cette date et mon application la convertira elle-même en raison du timezone défini pour la machine.

Je dois consigner certains events dans mon application dans une database, qui utilise également la méthode [date NSDate]. Cela signifie-t-il que la méthode [NSDate date] utilise également l'heure sans informations de timezone?

EDIT: Je pense que cela a quelque chose à voir avec le bug de l'heure d'été. Les choses que je vois sont exactement les mêmes que celles de l'application Clock, avec le bug qui fait que les gens se réveillent tard. De plus, TimeZone utilise par défaut le TimeZone actuellement défini sur votre appareil. Il doit donc restr le même jusqu'à ce que vous changiez le timezone de votre écran de parameters.

EDIT2: Ok, quelques tests supplémentaires:

 NSLog(@"CurrentDate: %@", [NSDate date]); NSLog(@"TZ: %@", [NSTimeZone defaultTimeZone]); 

Me donne les résultats suivants:

 2010-11-03 23:23:49.000 App[8578:207] CurrentDate: 2010-11-03 22:23:49 +0000 2010-11-03 23:23:49.001 App[8578:207] TZ: Europe/Amsterdam (GMT+01:00) offset 3600 

Voir Utilisation des fuseaux horaires . Vous devrez définir le timezone du calendar en utilisant la méthode -setTimeZone: de NSCalendar avant de commencer à lui requestr des dates.

C'est une question intéressante et j'ai travaillé à une solution pendant plusieurs heures. Ce sont mes conclusions:

 NSLog(@"CurrentDate: %@", [NSDate date]); 

Le code ci-dessus aura le même résultat que le code ci-dessous:

 NSLog(@"CurrentDate: %@", [[NSDate date] description]); 

La lecture de la reference de class NSDate produit cette documentation sur la méthode de description de NSDate .

La représentation n'est pas garantie pour restr constant entre les différentes versions du operating system. Pour mettre en forme une date, vous devez utiliser un object formateur de date à la place (voir NSDateFormatter et Guide de mise en forme des données)

J'ai également couru à travers la documentation pour descriptionWithLocale: (id) locale :

"Renvoie une représentation sous forme de string du récepteur en utilisant les parameters régionaux donnés."

Alors, changez votre code

 NSLog(@"CurrentDate: %@", [NSDate date]); 

À:

 NSLog(@"CurrentDate: %@", [[NSDate date] descriptionWithLocale:[NSLocale currentLocale]]); 

Ce qui devrait entraîner ce que vous cherchez. Et je peux aussi prouver que la [NSDate date] donne vraiment la bonne date, mais est simplement affichée avec une mauvaise méthode:

Nous pouvons utiliser le [today] (Wim Haanstra) pour créer deux dates.

dateDernierjour : 2010-11-02 23:59:00 +01
dateToday : 2010-11-03 24:01:00 +01

Ensuite, nous utilisons le code ci-dessous pour montrer les deux dates:

 NSLog(@"CurrentDate: %@", dateLastDay); NSLog(@"CurrentDate: %@", dateToday); 

Ou:

 NSLog(@"CurrentDate: %@", [dateLastDay description]); NSLog(@"CurrentDate: %@", [dateToday description]); 

Les deux groupes montrent les mêmes résultats, comme ceci: "2010-11-02 02:59:00 +0000" et "2010-11-02 02:01:00 +0000". On dirait que les deux dates ont le même 'jour', mais vraiment?

Maintenant nous comparons les jours des dates:

 NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar]; NSUInteger unitFlags = NSDayCalendarUnit; NSDateComponents *lastDayComponents = [gregorian components:unitFlags fromDate:dateLastDay]; NSDateComponents *todayComponents = [gregorian components:unitFlags fromDate:dateToday]; NSInteger lastDay = [lastDayComponents day]; NSInteger today = [todayComponents day]; return (lastDay == today) ? YES : NO; 

Nous obtiendrons NON! Bien que les deux dates semblent avoir le même jour, mois et année, ils ne le font pas. Cela n'apparaît que de cette façon parce que nous les avons montrés de la mauvaise façon.

Avez-vous essayé d'utiliser:

 NSDateFormatter *formatter = [[NSDateFormatter alloc] init]; [formatter setDateFormat:@"yyyy-MM-dd"]; todayAtOO = [formatter dateFromSsortingng:[formatter ssortingngFromDate:[NSDate date]]]; 

J'essaie toujours de comprendre exactement pourquoi ce bug se produit, mais je connais une solution. Définir le timezone de votre NSCalendar sur GMT avant de l'envoyer à dateFromComponents: résoudra le problème.

 [gregorian setTimeZone:[NSTimeZone timeZoneWithName:@"GMT"]]; 

PS, s'il y a une solution différente que vous avez trouvée sur la base de la suggestion de Joshua, pourriez-vous nous dire ce que c'est? Il semble que vous ayez résolu le problème depuis que vous avez accepté sa réponse, mais ce que vous avez fait n'est pas vraiment clair. Merci!

Pour autant que je puisse voir, il vous donne la bonne réponse si votre timezone est GMT + 1. Minuit, il est 23h00 le jour précédent à GMT.

Le problème est probablement dans le formatting de la date renvoyée pour la sortie. Il vous a donné une string pour GMT au lieu de votre locale actuelle.