2010-07-28 7 views
5

Was ist die einfachste Möglichkeit, von einem Datum zum nächsten zu wechseln?Einfachste Möglichkeit zum Looping zwischen zwei NSDates auf dem iPhone?

Was ich so etwas wie dies vom Konzept her ist will:

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

Dies funktioniert natürlich nicht: Es gibt keine dateByAddingDays:. Und selbst wenn, würde es eine breite Spur von Autoreleased-Objekten hinterlassen, die auf ihre Zerstörung warteten.

Hier ist, was ich habe gedacht:

  • Ich kann nicht nur eine NSTimeInterval hinzufügen, da die Anzahl der Sekunden in einem Tag variieren.
  • Ich könnte es in NSDateComponents brechen und einen Tag zu den Komponenten hinzufügen, dann wieder zusammenbauen. Aber das ist ein langer und hässlicher Code.

Also ich hoffe, jemand hat ein paar Möglichkeiten ausprobiert, und fand einen guten. Irgendwelche Ideen?

+0

Nun, der Haken ist, dass es keine DateByAddingDays gibt. :) –

Antwort

3

hinzufügen schnelle Aufzählung zu einer Daterange-Klasse:

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

Dies ist hässlich, aber die Hässlichkeit meines Datumsbereich Klasse beschränkt. Mein Client-Code ist nur:

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

Ich denke, dies ist wahrscheinlich ein Grund genug, eine Daterange-Klasse zu erstellen, wenn Sie eine nicht bereits haben.

7

eine oneDay Datum Komponente konstant einrichten und es immer wieder hinzufügen:

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

Diese noch die Spur der Autoreleased Objekte verlässt, aber dateByAddingComponents:toDate:options: verantwortlich ist. Ich bin mir nicht sicher, ob etwas dagegen unternommen werden kann.

4

Wie wäre es mit date = [Datum dateByAddingTimeInterval: 24 * 60 * 60] stattdessen?

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

Es ist ein guter Anfang, aber in den meisten Zeitzonen gibt es ein paar Tage pro Jahr mit einer anderen Anzahl von Stunden aufgrund der Sommerzeit. Wenn meine Zeit nahe Mitternacht ist, könnte das einen Unterschied machen. Um 12:05 Uhr könnte zum Beispiel am selben Tag um 23:05 Uhr werden. 23:05 Uhr Sonntag könnte am Dienstag 01.05 Uhr werden. –

Verwandte Themen