2010-11-03 30 views
6

Ich schreibe eine Kategorie in Xcode, die die aktuelle NSDate-Klasse erweitern würde. Ich möchte zwei Methoden hinzufügen, die ich regelmäßig verwende und irgendwie kann ich sie nicht richtig funktionieren lassen.NSDate für heute mit 00:00:00 als Zeit erhalten

Zur Zeit habe ich diesen Code:

+ (NSDate*) today 
{ 
    NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar]; 

    NSDateComponents *todayComponents = [gregorian components:(NSDayCalendarUnit | NSMonthCalendarUnit | NSYearCalendarUnit) fromDate:[NSDate date]]; 
    NSInteger theDay = [todayComponents day]; 
    NSInteger theMonth = [todayComponents month]; 
    NSInteger theYear = [todayComponents year]; 

    NSDateComponents *components = [[NSDateComponents alloc] init]; 
    [components setDay:theDay]; 
    [components setMonth:theMonth]; 
    [components setYear:theYear]; 

    NSDate* todayDate = [gregorian dateFromComponents:components]; 

    [components release]; 
    [gregorian release]; 

    return todayDate; 
} 

ich es will ein Datum wie folgt zurück: "2010-11-03 00.00.00 +01". Aber irgendwie hält mich die Zeitzone auf Fehler, weil dieser Code "2010-11-02 23:00:00 +0000" zurückgibt.

Kann jemand mir sagen, wie man diesen Code repariert, um das korrekte Datum tatsächlich zurückzugeben? Oder kann ich einfach dieses Datum verwenden und meine Anwendung wird es aufgrund der Zeitzone, auf die das Gerät eingestellt ist, selbst konvertieren.

Ich muss bestimmte Ereignisse in meiner App in einer Datenbank protokollieren, die auch nur die Methode [NSDate date] verwendet. Bedeutet das, dass die Methode [NSDate date] auch die Zeit ohne Zeitzoneninformationen verwendet?

EDIT: Ich denke, es hat etwas mit der Sommerzeit Bug zu tun. Die Dinge, die ich sehe, sind genau die gleichen wie die Uhr-App, mit dem Bug, der die Leute spät aufwachen lässt. Außerdem ist die TimeZone standardmäßig auf die Zeitzone eingestellt, die derzeit auf Ihrem Gerät eingestellt ist. Sie sollte also unverändert bleiben, bis Sie die Zeitzone auf dem Einstellungsbildschirm ändern.

EDIT2: Ok, einige weitere Tests:

NSLog(@"CurrentDate: %@", [NSDate date]); 
NSLog(@"TZ: %@", [NSTimeZone defaultTimeZone]); 

gibt mir die folgenden Ergebnisse:

2010-11-03 23:23:49.000 App[8578:207] CurrentDate: 2010-11-03 22:23:49 +0000 
2010-11-03 23:23:49.001 App[8578:207] TZ: Europe/Amsterdam (GMT+01:00) offset 3600 

Antwort

5

Using Time Zones See. Sie sollten die Zeitzone des Kalenders mithilfe der Methode -setTimeZone: von NSCalendar festlegen, bevor Sie nach Daten suchen.

+0

Nozzi ... wirklich? Folgen Sie mir? : P. Ich denke, es hat etwas mit dem Sommerzeit-Bug zu tun. Die Dinge, die ich sehe, sind genau die gleichen wie die Uhr-App, mit dem Bug, der die Leute spät aufwachen lässt. –

+0

Ich weiß nicht, diese @jnozzi Twitter Person, die Sie erwähnt. Was? Du hast es nicht erwähnt? VERDAMMT! Oh ja, ich bin es. ;-) Hmm. Ich habe davon nichts gehört. Könnte das iPhone bei Verwendung von Foundation-Kram markieren, da Mac/iOS in diesen Fällen nicht klar ist. :-) –

+0

Muhaha, ich weiß wo ich dich überall finde. Mein Beitrag wurde erneut aktualisiert. Muss ich diesen Offset wirklich hinzufügen, wenn ich [NSDate date] anrufe? Ich hoffte, dass das OS das automatisch machen würde. –

0

Soweit ich sehen kann, gibt es Ihnen die richtige Antwort, wenn Ihre Zeitzone GMT + 1 ist. Mitternacht ist Ihre Zeit um 23:00 Uhr am Vortag in GMT.

Das Problem besteht wahrscheinlich in der Formatierung des zurückgegebenen Datums für die Ausgabe. Es gibt Ihnen eine Zeichenfolge für GMT anstelle Ihres aktuellen Gebietsschemas.

1

Ich versuche immer noch herauszufinden, warum genau dieser Fehler passiert, aber ich weiß eine Lösung. Wenn Sie die Zeitzone Ihres NSCalendar auf GMT einstellen, bevor Sie dateFromComponents senden, wird das Problem gelöst.

[gregorian setTimeZone:[NSTimeZone timeZoneWithName:@"GMT"]]; 

PS, wenn es eine andere Lösung ist, die Sie auf Joshua Vorschlag basiert gefunden, können Sie uns wissen lassen, was es ist? Es scheint, als hättest du das Problem gelöst, seit du seine Antwort akzeptiert hast, aber es ist nicht wirklich klar, was du getan hast. Vielen Dank!

3

Dies ist eine interessante Frage, und ich arbeitete für viele Stunden an einer Lösung. Dies sind meine Ergebnisse:

NSLog(@"CurrentDate: %@", [NSDate date]); 

Der obige Code das gleiche Ergebnis gezeigt wird, wie der Code unten gezeigt:

NSLog(@"CurrentDate: %@", [[NSDate date] description]); 

Lesen durch die NSDate Class Reference produziert diese Dokumentation auf der NSDate desdescription Methode.

Es ist nicht garantiert, dass die Darstellung über verschiedene Versionen des Betriebssystems hinweg konstant bleibt. Um ein Datum zu formatieren, sollten Sie ein Datum Formatter-Objekt verwenden, statt (siehe NSDateFormatter und Datenformatierung Handbuch)

ich auch über die Dokumentation lief für descriptionWithLocale: (id) locale:

„Gibt eine Stringdarstellung des Empfängers die angegebene locale verwenden.“

So ändern Sie den Code

NSLog(@"CurrentDate: %@", [NSDate date]); 

An:

NSLog(@"CurrentDate: %@", [[NSDate date] descriptionWithLocale:[NSLocale currentLocale]]); 

, die für in dem, was Sie suchen, führen sollte. Und ich kann auch beweisen, dass das [NSDate date] wirklich das richtige Datum gibt, aber nur mit falscher Methode angezeigt wird:

Wir können die [today] (Wim Haanstra) verwenden, um zwei Daten zu erstellen.

dateLastDay: 2010-11-02 23:59:00 +01
dateToday: 2010-11-03 24:01:00 +01

Dann benutzen wir die Code unter den beiden Daten zeigen:

NSLog(@"CurrentDate: %@", dateLastDay); 
NSLog(@"CurrentDate: %@", dateToday); 

Oder:

Die beiden Gruppen zeigen die gleichen Ergebnisse, wie folgt aus: "2010-11- 22.59.00 +0000" und "2010-11- 23.01.00 +0000". Es sieht so aus, als ob die beiden Daten denselben "Tag" haben, aber wirklich?

Jetzt vergleichen wir die Tage der Termine:

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

NSUInteger unitFlags = NSDayCalendarUnit; 
NSDateComponents *lastDayComponents = [gregorian components:unitFlags fromDate:dateLastDay]; 
NSDateComponents *todayComponents = [gregorian components:unitFlags fromDate:dateToday]; 
NSInteger lastDay = [lastDayComponents day]; 
NSInteger today = [todayComponents day]; 

return (lastDay == today) ? YES : NO; 

Wir werden keine bekommen! Obwohl die beiden Daten den gleichen Tag, den gleichen Monat und das gleiche Jahr aufweisen, gilt dies NICHT. Es erscheint nur so, weil wir sie falsch dargestellt haben.

2

Haben Sie versucht, mit:

NSDateFormatter *formatter = [[NSDateFormatter alloc] init]; 
[formatter setDateFormat:@"yyyy-MM-dd"]; 
todayAtOO = [formatter dateFromString:[formatter stringFromDate:[NSDate date]]]; 
Verwandte Themen