2012-03-10 42 views
5

Quiero crear una matriz de rango que contenga días entre una fecha de inicio y finalización específica.Crear un rango de fechas

Por ejemplo, tengo una fecha de inicio el 1 de enero de 2012 y una fecha de finalización el 7 de enero de 2012. La matriz o rango debe contener una colección de objetos NSDate (7 en total).

¿Cómo puedo hacer esto?

Respuesta

7

NSCalendar es útil en este caso, ya que conoce el calendario en relación con las fechas. Entonces, al usar lo siguiente (suponiendo que tenga startDate y endData y que quiera incluir ambos en la lista), puede repetir las fechas, agregando un solo día (NSCalendar se encargará de ajustar los meses y el año bisiesto, etc.)

NSMutableArray *dateList = [NSMutableArray array]; 
NSCalendar *currentCalendar = [NSCalendar currentCalendar]; 
NSDateComponents *comps = [[NSDateComponents alloc] init]; 
[comps setDay:1]; 

[dateList addObject: startDate]; 
NSDate *currentDate = startDate; 
// add one the first time through, so that we can use NSOrderedAscending (prevents millisecond infinite loop) 
currentDate = [currentCalendar dateByAddingComponents:comps toDate:currentDate options:0]; 
while ([endDate compare: currentDate] != NSOrderedAscending) { 
    [dateList addObject: currentDate]; 
    currentDate = [currentCalendar dateByAddingComponents:comps toDate:currentDate options:0]; 
} 

[comps release];   
+0

Gracias, creo que esto es lo que estaba buscando. Sin embargo, la condición en el ciclo while siempre devuelve verdadero. '(LLDB) po endDate' ' (NSDate *) $ 6 = 0x06b9cc60 2012-03-11 00:12:42 + 0000' '(LLDB) po currentDate' ' (NSDate *) $ 7 = 0x06b9dd20 2012- 03-11 00:12:42 + 0000' Pero el valor de retorno todavía es verdadero. – joostevilghost

+0

Supongo que ejecutó esto con startDate = [NSDate date] y endDate = [NSDate date], que da como resultado dos fechas que no son idénticas, pero que son muy similares (en algunos milisegundos). Modifiqué esto para que sea seguro para esta condición, aunque si está usando un selector de fecha, probablemente no será un problema, ya que las fechas se establecerán manualmente en 00: 00: 00.0, no en 00:12 : 42.xx y 00: 12: 42.yy – gaige

+0

Esto funciona muy bien, pero me encontré con un problema donde me faltaba la fecha de finalización en noviembre. Resultó ser el horario de verano. Agregue esto a su declaración NSCalendar para evitar que '[currentCalendar setTimeZone: [NSTimeZone timeZoneWithAbbreviation: @" GMT "]]; // ignorar el horario de verano' – smokingoyster

1

Sólo crearlos y añadirlos a una serie ...

NSMutableArray *arr = [NSMutableArray array]; 
NSDateComponents *comps = [[[NSDateComponents alloc] init] autorelease]; 
[comps setMonth:1]; 
[comps setYear:2012]; 

for(int i=1;i<=7;i++) { 
    [comps setDay:i]; 
    [arr addObject:[[NSCalendar currentCalendar] dateFromComponents:comps]]; 
} 
0

de Apple doc: para calcular una secuencia de fechas, utilice el enumerateDatesStartingAfterDate: matchingComponents: Opciones: usingBlock: método en lugar de llamar a este método ( - nextDateAfterDate: matchingComponents: Opciones: ) en un bucle con el resultado de la iteración del bucle anterior.

A medida que fui, que se repetirá todas las fechas que coincidían con "matchingComponents" hasta acabar con la iteración "stop.memory = true"

let calendar = NSCalendar.currentCalendar() 
let startDate = calendar.startOfDayForDate(NSDate()) 
let finishDate = calendar.dateByAddingUnit(.Day, value: 10, toDate: startDate, options: []) 
let dayComponent = NSDateComponents() 
dayComponent.hour = 1 

calendar.enumerateDatesStartingAfterDate(startDate, matchingComponents: dayComponent, options: [.MatchStrictly]) { (date, exactMatch, stop) in 
    print(date) 
    if date!.compare(finishDate!) == NSComparisonResult.OrderedDescending { 
     // .memory gets at the value of an UnsafeMutablePointer 
     stop.memory = true 
    } 
} 
+0

Bienvenido a SO :) No ** solo ** publique un bloque de código como respuesta, pero también brinde una pequeña explicación para mejorar la calidad de su respuesta. –

Cuestiones relacionadas