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?

È stato utile?

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:

  1. Nessun allocazione di memoria diretta.
  2. secondi è invece un doppio di un numero intero.
  3. Nessun messaggio chiama.
  4. 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 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?

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

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top