2012-10-10 14 views
5

Editado 07/08/13: Apple tiene un excelente conjunto de videos WWDC que realmente me ayudaron a comprender las diversas clases de fecha y hora en Objective-C, y cómo realizar correctamente Cálculos/manipulaciones de tiempo con ellos.Programmatically getting the date "next Sunday at 5PM"

"Las soluciones a fecha común y hora Desafíos" (HD video, SD video, slides (PDF)) (WWDC 2013)
"Realizar cálculos del calendario" (SD video, slides (PDF)) (WWDC 2011)

Nota: los enlaces requieren una membresía de desarrollador de Apple gratuita.

Estoy escribiendo una aplicación para el podcast de un amigo. Ella transmite su programa en vivo todos los domingos a las 5 p.m., y me gustaría escribir un código en mi aplicación para programar opcionalmente una notificación local para ese momento, para que el usuario recuerde cuándo será el próximo show en vivo. ¿Cómo puedo obtener un objeto NSDate que represente "el próximo domingo, a las 5 pm, hora del Pacífico"? (Obviamente, esto tendría que ser convertidas en cualquier zona horaria del usuario está utilizando)

+2

Awesome linking and update. Bien en ti ! – uchuugaka

Respuesta

14

En primer lugar obtener el día actual de la semana:

NSDate *now = [NSDate date]; 
NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian]; 

NSDateComponents *dateComponents = [calendar components:NSCalendarUnitWeekday | NSCalendarUnitHour fromDate:now]; 
NSInteger weekday = [dateComponents weekday]; 

El Apple docs definen un día de la semana como:

día de la semana las unidades son los números del 1 al n, donde n es el número de días de la semana. Por ejemplo, en el calendario gregoriano, n es 7 Domingo está representado por 1.

Siguiente calcular cuántos días a añadir a llegar al siguiente domingo a las 5:

NSDate *nextSunday = nil; 
if (weekday == 1 && [dateComponents hour] < 5) { 
    // The next Sunday is today 
    nextSunday = now; 
} else { 
    NSInteger daysTillNextSunday = 8 - weekday; 
    int secondsInDay = 86400; // 24 * 60 * 60 
    nextSunday = [now dateByAddingTimeInterval:secondsInDay * daysTillNextSunday]; 
} 

Para obtenerlo a las 5:00 puede cambiar la hora y los minutos en nextSunday a 5:00. Eche un vistazo a get current date from [NSDate date] but set the time to 10:00 am

+0

Hay un error sutil en este código. El 'calendario' utiliza implícitamente la configuración regional actual. Si eso significa, por ejemplo, una zona horaria de Nueva Zelanda, difiere sustancialmente de la hora del Pacífico. El resultado puede ser que el código se calcule el próximo domingo en 6 o 7 días cuando el siguiente * Californian * Sunday-at-5 esté a solo unas horas de anticipación. –

+2

Además, el código para calcular 'nextSunday' se rompe cuando hay un cambio de luz natural en ese período. –