2010-07-28 12 views
5

Qual è il modo più semplice di passare da una data all'altra?Il modo più semplice per effettuare il loop tra due NSDate su iPhone?

Quello che voglio concettualmente è qualcosa di simile:

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

Questo non funziona, naturalmente: non c'è dateByAddingDays:. E anche se lo facesse, lascerebbe una vasta scia di oggetti autoreleased in attesa della loro distruzione.

Qui è quello che ho pensato:

  • Non posso aggiungere un NSTimeInterval, dal momento che il numero di secondi in un giorno può variare.
  • È possibile scomporlo in NSDateComponents e aggiungere un giorno ai componenti, quindi riassemblarlo. Ma questo è un codice lungo e brutto.

Così sto sperando che qualcuno ha provato alcune opzioni per questo, e ha trovato un buon compromesso. Qualche idea?

+0

Bene, il problema è che non c'è dataByAddingDays. :) –

risposta

3

Aggiungi enumerazione veloce a una classe 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; 
} 

Questo è brutto, ma la bruttezza è confinato alla mia classe di intervallo di date. Il mio codice cliente è solo:

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

Penso che questo è probabilmente una ragione sufficiente per creare una classe DateRange se non ne hai già uno.

7

Impostare una data ONEDAY costante componente e ripetutamente aggiungerlo:

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

questo lascia ancora tracce di oggetti autoreleased, ma dateByAddingComponents:toDate:options: è responsabile. Non sono sicuro che si possa fare qualcosa al riguardo.

4

Come sull'utilizzo date = [data dateByAddingTimeInterval: 24 * 60 * 60] invece?

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

È un buon inizio, ma nella maggior parte dei fusi orari ci sono un paio di giorni all'anno con un diverso numero di ore a causa dell'ora legale. Se il mio tempo è vicino a mezzanotte, questo potrebbe fare la differenza. Le 12:05 potrebbero diventare le 23.05 dello stesso giorno, per esempio. 23.05 Domenica potrebbe diventare 1:05 AM martedì. –

Problemi correlati