Je commence à développer pour l'iPhone et, en tant que tel, je regarde différents tutoriels en ligne et j'essaye différentes choses par moi-même. Actuellement, j'essaie de créer un compte à rebours jusqu'à minuit. Pour obtenir le nombre d'heures, de minutes et de secondes, procédez comme 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 = [NSString stringWithFormat:@"%02d:%02d:%02d", hour, min,sec];
Cependant, chaque endroit que j'utilise -dateWithCalendarFormat:timeZone:
J'ai 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?
De plus, j’ai remarqué à différents endroits et à différents moments que l’astérisque (*) est situé soit juste après le temps NSDate* now
ou juste avant la variable NSDate *now
. Quelle est la différence entre les deux et pourquoi voudriez-vous utiliser l'un par rapport à 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 simplement une question de préférence. Du point de 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"];
NSString *dateString = [dateFormatter stringFromDate:currDate];
NSLog(@"%@",dateString);
-> 20.01.2011 10:36:02
Vous pouvez aussi utiliser:
CFGregorianDate currentDate = CFAbsoluteTimeGetGregorianDate(CFAbsoluteTimeGetCurrent(), CFTimeZoneCopySystem());
countdownLabel.text = [NSString stringWithFormat:@"%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:
// 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"];
NSString* dateString = [formatter stringFromDate: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 = [NSString stringWithFormat:@"%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 = [NSString stringWithFormat:@"%02d:%02d:%02d", hour, minute, second];
De plus, j’ai remarqué à différents endroits et à différents moments l’astérisque (
*
) est situé soit juste après le tempsNSDate* now
ou juste avant la variableNSDate *now
. Quelle est la différence entre les deux et pourquoi voudriez-vous utiliser l'un par rapport à l'autre?
Le compilateur s'en fiche, 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 vous trompez. C'est juste int
.
L’autre façon de rendre cela plus clair en gardant le * à côté de la variable à laquelle il appartient:
int *a, b;
Bien sûr, il y a deux façons qui sont encore plus claires que cela:
int b, *a;
int *a;
int b;
Vous devez faire quelque chose dans le sens suivant:
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 dateWithNaturalLanguageString:@"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 inférieure à la seconde avec la conversion de NSTimeInterval sur un int, mais cela ne devrait pas avoir d'importance.
NSDate* now
et NSDate *now
sont la même chose: un pointeur sur un objet NSDate.
Vous voudrez probablement utiliser descriptionWithCalendarFormat: timeZone: locale: plutôt que dateWithCalendarFormat: - ce dernier renvoie un NSCalendarDate, dont les documents sont censés être obsolètes à 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 obtenir 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);
+ (NSString *)displayCurrentTimeWithAMPM
{
NSDateFormatter *outputFormatter = [[NSDateFormatter alloc] init];
[outputFormatter setDateFormat:@"h:mm aa"];
NSString *dateTime = [NSString stringWithFormat:@"%@",[outputFormatter stringFromDate:[NSDate date]]];
return dateTime;
}
retour 03h33
Il m'a fallu un certain temps pour savoir pourquoi l'application exemple fonctionnait, 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) sur laquelle l'iphone sdk (j'utilise la version 3.0) n'est plus prise en charge.
Par conséquent, l'exemple d'application (de about.com, http://www.appsamuck.com/day1.html ) fonctionne, mais le nôtre ne fonctionne pas.
CFGregorianDate currentDate = CFAbsoluteTimeGetGregorianDate(CFAbsoluteTimeGetCurrent(), CFTimeZoneCopySystem());
countdownLabel.text = [NSString stringWithFormat:@"%02d:%02d:%2.0f", currentDate.hour, currentDate.minute, currentDate.second];
Mark avait raison, ce code est BEAUCOUP plus efficace pour gérer les dates heures et minutes. Mais il a oublié le @ au début de la déclaration de chaîne de format.