Pregunta

Estoy empezando a desarrollar para iPhone y, como tal, estoy viendo diferentes tutoriales en línea y probando algunas cosas diferentes yo mismo.Actualmente, estoy intentando crear una cuenta regresiva hasta la medianoche.Para obtener la cantidad de horas, minutos y segundos, hago lo siguiente (que encontré en alguna 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];

Sin embargo, cada lugar que uso -dateWithCalendarFormat:timeZone: Obtuve el siguiente error:

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')

Esto parece algo muy simple.¿Qué me estoy perdiendo?

Además, he notado que en diferentes lugares y en diferentes momentos el asterisco (*) se encuentra justo después de la hora NSDate* now o justo antes de la variable NSDate *now.¿Cuál es la diferencia entre los dos y por qué usarías uno frente al otro?

¿Fue útil?

Solución

Debe utilizar el siguiente:

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];

No hay ninguna diferencia entre NSDate * ahora * NSDate y ahora, es sólo una cuestión de preferencia. Desde el punto de vista del compilador, nada cambia.

Otros consejos

Tiene problemas con iOS 4.2? Utilizar este código:

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

También puede usar:


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

Creo que esto tiene las siguientes ventajas:

  1. No asignación de memoria directa.
  2. segundos es un doble en vez de un entero.
  3. No se llama mensaje.
  4. más rápido.

// puede obtener la fecha / hora con el siguiente código:

    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];

Reemplazar esta:

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 esta:

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];
  

Además, me he dado cuenta en diferentes lugares y en diferentes momentos del asterisco (*) se encuentra ya sea inmediatamente después de la hora NSDate* now o justo antes de la variable NSDate *now. ¿Cuál es la diferencia entre los dos y ¿para qué usar uno contra el otro?

El compilador no le importa, pero poniendo el asterisco antes de que el espacio puede ser engañosa. Aquí está mi ejemplo:

int* a, b;

¿Cuál es el tipo de b?

Si pensó que era int *, estás equivocado. Es sólo int.

La otra forma hace que esta un poco más clara, manteniendo el * junto a la variable Pertenece a:

int *a, b;

Por supuesto, hay dos formas que son aún más claro que eso:

int b, *a;

int *a;
int b;

Es necesario hacer algo en la línea de lo siguiente:

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

Y así sucesivamente.

Aquí hay otra manera:

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;

Se pierde precisión por debajo con el elenco de la NSTimeInterval a un int, pero eso no debería importar.

NSDate* now y NSDate *now son lo mismo:un puntero a un objeto NSDate.

Probablemente quieras usar descripciónWithCalendarFormat:timeZone:locale: en vez de fechaConCalendarioFormato: - este último devuelve un NSCalendarDate, que según los documentos está programado para quedar obsoleto en algún momento.

Cartel original - la forma en que está la determinación de segundos hasta la medianoche no funcionará en un día en el horario de verano comienza o termina. Aquí hay un trozo de código que muestra cómo hacerlo ... Será en el número de segundos (un NSTimeInterval); que puede hacer la división / módulo / etc para bajar a lo que sea necesario.

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);

No hay ninguna diferencia en la ubicación del asterisco (en en C, que Obj-C se basa en, no importa). Es puramente preferencia (estilo).

Me tomó un tiempo para localizar por qué funciona la aplicación de la muestra, pero la mía no lo hacen.

La biblioteca (Foundation.Framework) que el autor se refiere a es la biblioteca del sistema (de OS) en el que el iPhone SDK (estoy usando 3.0) no se admite ninguna más.

Por lo tanto la aplicación de la muestra (de about.com, http://www.appsamuck.com/day1 .html ) funciona pero la nuestra no lo hacen.

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

Marcos tenía razón este código es mucho más eficiente para manejar fechas y horas minutos segundos. Pero se olvidó de la @ al comienzo de la declaración cadena de formato.

+ (NSString *)displayCurrentTimeWithAMPM 
{
    NSDateFormatter *outputFormatter = [[NSDateFormatter alloc] init];
    [outputFormatter setDateFormat:@"h:mm aa"];

    NSString *dateTime = [NSString stringWithFormat:@"%@",[outputFormatter stringFromDate:[NSDate date]]];

    return dateTime;
}

retorno 3:33 AM

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top