2008-10-08 6 views
12

Gibt es einen besseren Weg, dies zu tun?Gibt es einen besseren Weg, morgen Mitternacht zu finden?

-(NSDate *)getMidnightTommorow { 
    NSCalendarDate *now = [NSCalendarDate date]; 
    NSCalendarDate *tomorrow = [now dateByAddingYears:0 months:0 days:1 hours:0 minutes:0 seconds:0]; 
    return [NSCalendarDate dateWithYear:[tomorrow yearOfCommonEra] 
            month:[tomorrow monthOfYear] 
            day:[tomorrow dayOfMonth] 
            hour:0 
           minute:0 
           second:0 
           timeZone:[tomorrow timeZone]]; 
} 

Bitte beachte, dass ich immer die nächste Mitternacht will, auch wenn es Mitternacht sein geschieht, wenn ich diesen Anruf machen, aber wenn es passiert, 23.59.59 zu sein, ich natürlich will die Mitternacht, die kommt in einer Sekunde.

Die natürliche Sprachfunktionen scheinen flockig, und ich bin nicht sicher, was Cocoa tun würde, wenn ich 32 im „Tag“ Feld übergeben. (Wenn das funktionieren würde, ich könnte die [jetzt dateByAddingYears: ...] fallen call)

Antwort

25

Vom documentation:

Verwendung von NSCalendarDate stark abgeraten. Es ist noch nicht veraltet, aber es in der nächsten Haupt O Release nach Mac OS X v10.5 sein kann. Für kalendarischen Berechnungen, sollten Sie verwenden geeignete Kombinationen von NSCalendar, NSDate und NSDateComponents, wie in Kalender in Dates and Times Programming Topics for Cocoa beschrieben.

dass die Beratung Folgende:

NSDate *today = [NSDate date]; 

NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar]; 

NSDateComponents *components = [[NSDateComponents alloc] init]; 
components.day = 1; 
NSDate *tomorrow = [gregorian dateByAddingComponents:components toDate:today options:0]; 
[components release]; 

NSUInteger unitFlags = NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit; 
components = [gregorian components:unitFlags fromDate:tomorrow]; 
components.hour = 0; 
components.minute = 0; 

NSDate *tomorrowMidnight = [gregorian dateFromComponents:components]; 

[gregorian release]; 
[components release]; 

(Ich bin nicht sicher ohne Weiteres, wenn dies die effizienteste Implementierung ist, aber es sollte als Zeiger in der richtigen Richtung dienen.)

Hinweis : Theoretisch können Sie hier die Menge an Code reduzieren, indem Sie ein Datumskomponentenobjekt mit Werten zulassen, die größer sind als der Bereich normaler Werte für die Komponente (z. B. einfach 1 zur Tageskomponente hinzufügen, was zu einem Wert von 32 führen kann). . kann jedoch, obwohl dateFromComponents: tolerieren out-of-bounds Werte, es ist nicht garantiert. Es wird dringend empfohlen, sich nicht darauf zu verlassen.

+0

Und nach aus, dass Zeiger, es sieht so aus, als könnte ich das meiste ausschneiden, da dateFromComponents * Tage nach dem Ende des Monats zu tolerieren scheint. – Dre

+0

dateFromComponents * kann Werte außerhalb der Grenzen tolerieren, aber es ist nicht garantiert. Es wird dringend empfohlen, sich nicht darauf zu verlassen. – mmalc

+0

Ich bin an der Ostküste, und alle heute Tag, als ich die obige Umwandlung ich 01.00 erhalten (Meine Zeit offet ist -5 Stunden, aber es scheint, dass NSCalendar überzeugt ist, dass es -4 Stunden. (Auch wenn ich ausdrücklich Stellen Sie die Zeitzone ein –

0

Konvertieren Sie Ihr aktuelles Datum und die Uhrzeit auf ein Unix-Datum (Sekunden seit 1970) oder DOS-Stil (seit 1980), als 24 Stunden hinzufügen und zurück zu konvertieren. Stellen Sie dann die Stunden, Minuten und Sekunden auf Null zurück, um Mitternacht zu erreichen.

+0

Funktioniert nicht für einige Fälle von Sommerzeit. – Andrew

7

Nein - es wird auf die gleiche Weise Mitternacht heute finden benutzen zu.

+0

awww c'mon. das war lustig! – loudej

+1

Ich habe Angst Leute hier haben sehr defekte Ironie/Humor Detektoren. Wenn Sie Ihre witzigen Kommentare nicht als solche markieren, werden Sie downvoted. BTDT. – JesperE

+0

Ich werde deine Antwort nicht ablehnen, aber selbst wenn es lustig ist, was ist der Witz? Eine oberflächliche kurze Antwort, die die Details der Frage ignoriert? Sie könnten Ihren "Witz" für jede einzelne technische Frage zu SO verwenden. Deshalb ist es nicht lustig. –

1
[NSDate dateWithNaturalLanguageString:@"midnight tomorrow"]; 
+0

Interessante Herangehensweise (und ich habe es dafür hochgestuft), aber beachten Sie die Vorsicht in der Dokumentation: "Es kann zu unerwarteten Ergebnissen führen, und es wird dringend davon abgeraten." –

+0

Danke, ich suchte nach einer besseren Lösung auch seit dem iPhone SDK mag nicht, wenn ich es benutze, aber es funktioniert immer noch für jetzt :) – user58338

4
NSCalendar *gregorian = [[[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar] autorelease]; 

NSDate *tomorrow = [NSDate dateWithTimeIntervalSinceNow:(24 * 60 * 60)]; 

NSDateComponents *components = [gregorian components:(NSYearCalendarUnit | 
                 NSMonthCalendarUnit | 
                 NSDayCalendarUnit) 
              fromDate:tomorrow]; 

NSDate *midnight = [gregorian dateFromComponents:components]; 
+6

Jedes Mal, wenn ein Programmierer einen Tag als 60 * 60 * 24 definiert, stirbt eine Schaltsekunde. Tu das nicht. – cbowns

0

Sie könnten auf diese Weise versuchen:

NSCalendar *calendar = [NSCalendar currentCalendar]; 
NSDateComponents *comps = [[NSDateComponents alloc] init]; 
[comps setDay:1]; 
NSDate *tomorrow = [calendar dateByAddingComponents:comps toDate:[NSDate date] options:0]; //it gives us tomorrow with current time 
NSDate *midnight = [calendar startOfDayForDate:tomorrow]; //here we get next midnight 

Es ist auch einfach, das Sekunden-Intervall abrufen, wenn erforderlich, um eine NSTimer einzurichten:

double intervalToMidnight = midnight.timeIntervalSinceNow;