Comment puis-je obtenir la date actuelle dans Cocoa

Je commence à développer pour l’iPhone et à ce titre, je regarde différents didacticiels en ligne et j’essaie moi-même différentes choses. Actuellement, j’essaie de créer un compte à rebours jusqu’à minuit. Pour obtenir le nombre d’heures, de minutes et de secondes, je fais ce qui suit (que j’ai trouvé quelque part):

NSDate* now = [NSDate date]; int hour = 23 - [[now dateWithCalendarFormat:nil timeZone:nil] hourOfDay]; int min = 59 - [[now dateWithCalendarFormat:nil timeZone:nil] minuteOfHour]; int sec = 59 - [[now dateWithCalendarFormat:nil timeZone:nil] secondOfMinute]; countdownLabel.text = [NSSsortingng ssortingngWithFormat:@"%02d:%02d:%02d", hour, min,sec]; 

Cependant, chaque endroit où j’utilise -dateWithCalendarFormat:timeZone: j’obtiens l’erreur suivante:

 warning: 'NSDate' may not respond to '-dateWithCalendarFormat:timeZone:' (Messages without a matching method signature will be assumed to return 'id' and accept '...' as arguments.) warning: no '-hourOfDay' method found error: invalid operands to binary - (have 'int' and 'id') 

Cela semble être quelque chose de très simple. Qu’est-ce que je rate?

En outre, j’ai remarqué à différents endroits et à différents moments que l’astérisque (*) se trouve juste après l’heure NSDate* now ou juste avant la variable NSDate *now . Quelle est la différence entre les deux et pourquoi utiliseriez-vous l’un contre l’autre?

Vous devez utiliser les éléments suivants:

 NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar]; NSDateComponents *dateComponents = [gregorian components:(NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit) fromDate:yourDateHere]; NSInteger hour = [dateComponents hour]; NSInteger minute = [dateComponents minute]; NSInteger second = [dateComponents second]; [gregorian release]; 

Il n’y a pas de différence entre NSDate * maintenant et NSDate * maintenant, c’est juste une question de préférence. Du sharepoint vue du compilateur, rien ne change.

Vous avez des problèmes avec iOS 4.2? Utilisez ce code:

 NSDate *currDate = [NSDate date]; NSDateFormatter *dateFormatter = [[NSDateFormatter alloc]init]; [dateFormatter setDateFormat:@"dd.MM.YY HH:mm:ss"]; NSSsortingng *dateSsortingng = [dateFormatter ssortingngFromDate:currDate]; NSLog(@"%@",dateSsortingng); 

-> 20.01.2011 10:36:02

Vous pouvez aussi utiliser:

 CFGregorianDate currentDate = CFAbsoluteTimeGetGregorianDate(CFAbsoluteTimeGetCurrent(), CFTimeZoneCopySystem()); countdownLabel.text = [NSSsortingng ssortingngWithFormat:@"%02d:%02d:%02.0f", currentDate.hour, currentDate.minute, currentDate.second]; CFRelease(currentDate); // Don't forget this! VERY important 

Je pense que cela présente les avantages suivants:

  1. Aucune allocation de mémoire directe.
  2. Les secondes sont un double au lieu d’un entier.
  3. Aucun appel de message.
  4. Plus rapide.

// vous pouvez obtenir la date / heure actuelle avec le code suivant:

  NSDate* date = [NSDate date]; NSDateFormatter* formatter = [[NSDateFormatter alloc] init]; NSTimeZone *destinationTimeZone = [NSTimeZone systemTimeZone]; formatter.timeZone = destinationTimeZone; [formatter setDateStyle:NSDateFormatterLongStyle]; [formatter setDateFormat:@"MM/dd/yyyy hh:mma"]; NSSsortingng* dateSsortingng = [formatter ssortingngFromDate:date]; 

Remplacez ceci:

 NSDate* now = [NSDate date]; int hour = 23 - [[now dateWithCalendarFormat:nil timeZone:nil] hourOfDay]; int min = 59 - [[now dateWithCalendarFormat:nil timeZone:nil] minuteOfHour]; int sec = 59 - [[now dateWithCalendarFormat:nil timeZone:nil] secondOfMinute]; countdownLabel.text = [NSSsortingng ssortingngWithFormat:@"%02d:%02d:%02d", hour, min,sec]; 

Avec ça:

 NSDate* now = [NSDate date]; NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar]; NSDateComponents *dateComponents = [gregorian components:(NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit) fromDate:now]; NSInteger hour = [dateComponents hour]; NSInteger minute = [dateComponents minute]; NSInteger second = [dateComponents second]; [gregorian release]; countdownLabel.text = [NSSsortingng ssortingngWithFormat:@"%02d:%02d:%02d", hour, minute, second]; 

En outre, j’ai remarqué à différents endroits et à différents moments que l’astérisque ( * ) se trouve juste après l’heure NSDate* now ou juste avant la variable NSDate *now . Quelle est la différence entre les deux et pourquoi utiliseriez-vous l’un contre l’autre?

Le compilateur ne se soucie pas, mais placer l’astérisque avant l’espace peut être trompeur. Voici mon exemple:

 int* a, b; 

Quel est le type de b ?

Si vous avez deviné int * , vous avez tort. C’est juste int .

L’autre façon rend ceci légèrement plus clair en gardant le * à côté de la variable à laquelle il appartient:

 int *a, b; 

Bien sûr, il y a deux manières encore plus claires que cela:

 int b, *a; int *a; int b; 

Vous devez faire quelque chose comme suit:

 NSDate *now = [NSDate date]; NSCalendar *calendar = [NSCalendar currentCalendar]; NSDateComponents *components = [calendar components:NSHourCalendarUnit fromDate:now]; NSLog(@"%d", [components hour]); 

Etc.

Voici un autre moyen:

 NSDate *now = [NSDate date]; //maybe not 100% approved, but it works in English. You could localize if necessary NSDate *midnight = [NSDate dateWithNaturalLanguageSsortingng:@"midnight tomorrow"]; //num of seconds between mid and now NSTimeInterval timeInt = [midnight timeIntervalSinceDate:now]; int hours = (int) timeInt/3600; int minutes = ((int) timeInt % 3600) / 60; int seconds = (int) timeInt % 60; 

Vous perdez une précision en seconde avec la conversion de NSTimeInterval en int, mais cela ne devrait pas avoir d’importance.

NSDate* now et NSDate *now sont la même chose: un pointeur sur un object NSDate.

Vous souhaiterez probablement utiliser descriptionWithCalendarFormat: timeZone: locale: plutôt que dateWithCalendarFormat: – ce dernier retourne un NSCalendarDate, dont la date de publication est prévue à un moment donné.

Affiche originale – la façon dont vous déterminez les secondes jusqu’à minuit ne fonctionnera pas un jour où l’heure avancée commence ou se termine. Voici un morceau de code qui montre comment le faire … Ce sera en nombre de secondes (un NSTimeInterval); vous pouvez faire la division / module / etc pour arriver à tout ce dont vous avez besoin.

 NSDateComponents *dc = [[NSCalendar currentCalendar] components:NSDayCalendarUnit|NSMonthCalendarUnit|NSYearCalendarUnit fromDate:[NSDate date]]; [dc setDay:dc.day + 1]; NSDate *midnightDate = [[NSCalendar currentCalendar] dateFromComponents:dc]; NSLog(@"Now: %@, Tonight Midnight: %@, Hours until midnight: %.1f", [NSDate date], midnightDate, [midnightDate timeIntervalSinceDate:[NSDate date]] / 60.0 / 60.0); 

Il n’y a pas de différence dans l’emplacement de l’astérisque (at en C, sur lequel Obj-C est basé, peu importe). C’est de la préférence pure (style).

Il m’a fallu un certain temps pour trouver pourquoi l’application exemple fonctionne, mais pas la mienne.

La bibliothèque (Foundation.Framework) à laquelle l’auteur fait référence est la bibliothèque système (à partir du système d’exploitation) où iphone sdk (J’utilise 3.0) n’est plus supporté.

Par conséquent, l’exemple d’application (à partir de about.com, http://www.appsamuck.com/day1.html ) fonctionne, mais pas le nôtre.

 CFGregorianDate currentDate = CFAbsoluteTimeGetGregorianDate(CFAbsoluteTimeGetCurrent(), CFTimeZoneCopySystem()); countdownLabel.text = [NSSsortingng ssortingngWithFormat:@"%02d:%02d:%2.0f", currentDate.hour, currentDate.minute, currentDate.second]; 

Mark a raison, ce code est BEAUCOUP plus efficace pour gérer les dates heures min et s. Mais il a oublié le @ au début de la déclaration de format.

 + (NSSsortingng *)displayCurrentTimeWithAMPM { NSDateFormatter *outputFormatter = [[NSDateFormatter alloc] init]; [outputFormatter setDateFormat:@"h:mm aa"]; NSSsortingng *dateTime = [NSSsortingng ssortingngWithFormat:@"%@",[outputFormatter ssortingngFromDate:[NSDate date]]]; return dateTime; } 

retour 03h33