2010-07-28 7 views
5

¿Cuál es la forma más sencilla de pasar de una fecha a otra?¿La forma más simple de recorrer dos NSDates en el iPhone?

Lo que quiero es conceptualmente algo como esto:

for (NSDate *date = [[startDate copy] autorelease]; [date compare: endDate] < 0; 
    date = [date dateByAddingDays: 1]) { 
    // do stuff here 
} 

Esto no funciona, por supuesto: no hay dateByAddingDays:. E incluso si lo hiciera, dejaría una amplia estela de objetos liberados a la espera de su destrucción.

Esto es lo que he pensado:

  • No puedo añadir una NSTimeInterval, ya que el número de segundos en un día puede variar.
  • Podría descomponerlo en NSDateComponents y agregar un día a los componentes, luego volver a montarlo. Pero ese es un código largo y feo.

Así que espero que alguien haya probado algunas opciones para esto, y haya encontrado una buena. ¿Algunas ideas?

+0

Bueno, el problema es que no hay fecha de Adición de Dias. :) –

Respuesta

3

Añadir enumeración rápida a una clase DateRange:

- (NSUInteger)countByEnumeratingWithState: (NSFastEnumerationState *)state 
            objects: (id *)stackbuf 
            count: (NSUInteger)len; 
{ 
    NSInteger days = 0; 
    id current = nil; 
    id components = nil; 
    if (state->state == 0) 
    { 
     current = [NSCalendar currentCalendar]; 
     state->mutationsPtr = &state->extra[0]; 
     components = [current components: NSDayCalendarUnit 
           fromDate: startDate 
            toDate: endDate 
           options: 0]; 
     days = [components day]; 
     state->extra[0] = days; 
     state->extra[1] = (uintptr_t)current; 
     state->extra[2] = (uintptr_t)components; 
    } else { 
     days = state->extra[0]; 
     current = (NSCalendar *)(state->extra[1]); 
     components = (NSDateComponents *)(state->extra[2]); 
    } 
    NSUInteger count = 0; 
    if (state->state <= days) { 
     state->itemsPtr = stackbuf; 
     while ((state->state <= days) && (count < len)) { 
      [components setDay: state->state]; 
      stackbuf[count] = [current dateByAddingComponents: components 
                 toDate: startDate 
                 options: 0]; 
      state->state++; 
      count++; 
     } 
    } 
    return count; 
} 

Ésta es feo, pero la fealdad se limita a mi clase de intervalo de fechas. Mi código de cliente es:

for (id date in dateRange) { 
    NSLog(@"%@ in [%@,%@]", date, startDate, endDate); 
} 

Creo que esto es probablemente una razón suficiente para crear una clase DateRange si no tiene uno ya.

7

Establecer un componente de fecha constante y repetidamente ONEDAY agregarlo:

NSCalendar *calendar = [NSCalendar currentCalendar]; 
    NSDateComponents *oneDay = [[NSDateComponents alloc] init]; 
    [oneDay setDay: 1]; 

    for (id date = [[startDate copy] autorelease]; [date compare: endDate] <= 0; 
     date = [calendar dateByAddingComponents: oneDay 
             toDate: date 
             options: 0]) { 
     NSLog(@"%@ in [%@,%@]", date, startDate, endDate); 
    } 

esto todavía deja el rastro de objetos autoreleased, pero dateByAddingComponents:toDate:options: es responsable. No estoy seguro de que se pueda hacer algo al respecto.

4

¿Qué le parece usar date = [date dateByAddingTimeInterval: 24 * 60 * 60] en su lugar?

for (NSDate *date = [[startDate copy] autorelease]; [date compare: endDate] < 0; 
date = [date dateByAddingTimeInterval:24 * 60 * 60]) { 
    NSLog(@"%@ in [%@,%@]", date, startDate, endDate); 
} 
+1

Es un buen comienzo, pero en la mayoría de las zonas horarias hay un par de días por año con un número diferente de horas debido al horario de verano. Si mi hora es cercana a la medianoche, esto podría marcar la diferencia. 12:05 AM podría convertirse en 11:05 PM en el mismo día, por ejemplo. 11:05 PM El domingo podría convertirse en 1:05 AM el martes. –

Cuestiones relacionadas