Come faccio ad avere la data corrente in Cocoa
-
21-08-2019 - |
Domanda
Mi sto iniziato a sviluppare per l'iPhone e come tale sto guardando diversi tutorial online, così come provare alcune cose diverse io. Attualmente, sto cercando di creare un conto alla rovescia fino a mezzanotte. Per ottenere il numero di ore, minuti e secondi, faccio la seguente (che ho trovato da qualche parte):
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];
Tuttavia, ogni luogo io uso -dateWithCalendarFormat:timeZone:
ottengo il seguente errore:
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')
Questo mi sembra una cosa molto semplice. Che cosa mi manca?
Inoltre, ho notato in luoghi diversi e in tempi diversi l'asterisco (*) si trova sia a destra dopo il tempo NSDate* now
o di destra prima che la variabile NSDate *now
. Qual è la differenza tra i due e perché si dovrebbe usare uno contro l'altro?
Soluzione
È necessario utilizzare il seguente:
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];
Non c'è alcuna differenza tra NSDate * ora e NSDate * adesso, è solo una questione di preferenza. Dal punto di vista del compilatore, non cambia nulla.
Altri suggerimenti
Hai problemi con iOS 4.2? Di questo codice:
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
È inoltre possibile utilizzare:
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
Credo che questo ha i seguenti vantaggi:
- Nessun allocazione di memoria diretta.
- secondi è invece un doppio di un numero intero.
- Nessun messaggio chiama.
- Più veloce.
// è possibile ottenere data / ora con il seguente codice:
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];
Sostituire questa:
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];
Con questa:
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];
Inoltre, ho notato in luoghi diversi e in tempi diversi l'asterisco (
*
) si trova sia a destra dopo il tempoNSDate* now
o di destra prima che la variabileNSDate *now
. Qual è la differenza tra i due e perché si dovrebbe usare uno contro l'altro?
Il compilatore non si cura, ma mettere l'asterisco prima che lo spazio può essere fuorviante. Ecco il mio esempio:
int* a, b;
Qual è il tipo di b
?
Se avete indovinato int *
, ti sbagli. E 'solo int
.
L'altro modo rende leggermente più chiara mantenendo il * accanto alla variabile esso appartiene:
int *a, b;
Naturalmente, ci sono due modi che sono ancora più chiaro di quello:
int b, *a;
int *a;
int b;
Hai bisogno di fare qualcosa sulla falsariga di quanto segue:
NSDate *now = [NSDate date];
NSCalendar *calendar = [NSCalendar currentCalendar];
NSDateComponents *components = [calendar components:NSHourCalendarUnit fromDate:now];
NSLog(@"%d", [components hour]);
E così via.
Ecco un altro modo:
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;
Si perde precisione inferiore al secondo con il cast del NSTimeInterval ad un int, ma che non dovrebbe importare.
NSDate* now
e NSDate *now
sono la stessa cosa:. Un puntatore ad un oggetto NSDate
Probabilmente si desidera utilizzare descriptionWithCalendarFormat: fuso orario: locale: , piuttosto che dateWithCalendarFormat: - quest'ultimo restituisce un NSCalendarDate, che i documenti dicono che è stato programmato per essere deprecato ad un certo punto.
Locandina originale - il modo in cui si sta determinando secondi fino a mezzanotte non funziona su un giorno in cui l'ora legale inizia o finisce. Ecco un pezzo di codice che mostra come si fa ... Sarà in numero di secondi (un NSTimeInterval); si può fare la divisione / modulo / etc per arrivare fino a quello che vi serve.
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);
Non c'è differenza nella posizione del asterisco (a in C, che Obj-C si basa su, non importa). E 'puramente preferenza (stile).
Mi c'è voluto un po 'per localizzare perché le opere di applicazione di esempio, ma il mio non lo fanno.
La libreria (Foundation.Framework) che l'autore si riferiscono a è la libreria di sistema (da OS) in cui l'iPhone SDK (sto usando 3.0) non è il supporto più.
Pertanto l'applicazione di esempio (da about.com, http://www.appsamuck.com/day1 .html ) funziona ma la nostra non lo fanno.
CFGregorianDate currentDate = CFAbsoluteTimeGetGregorianDate(CFAbsoluteTimeGetCurrent(), CFTimeZoneCopySystem());
countdownLabel.text = [NSString stringWithFormat:@"%02d:%02d:%2.0f", currentDate.hour, currentDate.minute, currentDate.second];
Mark aveva ragione di questo codice è molto più efficiente per gestire date ore min e sec. Ma si è dimenticato l'@ all'inizio della dichiarazione di stringa di formato.
+ (NSString *)displayCurrentTimeWithAMPM
{
NSDateFormatter *outputFormatter = [[NSDateFormatter alloc] init];
[outputFormatter setDateFormat:@"h:mm aa"];
NSString *dateTime = [NSString stringWithFormat:@"%@",[outputFormatter stringFromDate:[NSDate date]]];
return dateTime;
}
ritorno 03:33