2011-01-05 14 views
7

Ich muss etwas kleines sie vermissen, aber kann es nicht herausfinden. Der Versuch, ein Datum für den Vergleich zu schaffen, aber ich kann nicht scheinen current von GMT EST zum Ausgleich:NSDate - Offset der Zeitzone

// current date (gmt) // 
NSDate *currentDate = [NSDate date]; 

NSTimeZone *currentDateTimeZone = [NSTimeZone timeZoneWithAbbreviation:@"EST"]; 

NSDateFormatter *currentDateFormat = [[NSDateFormatter alloc]init]; 
[currentDateFormat setTimeZone:currentDateTimeZone]; 
[currentDateFormat setDateFormat:@"yyyy-MM-dd HH:mm:ss zzz"]; 

NSString *currentDateString = [currentDateFormat stringFromDate:currentDate]; 
NSLog(@"currentDateString: %@", currentDateString); // returns 2011-01-05 13:30:30 EST 

NSDate *currentDateWithOffset = [currentDateFormat dateFromString:currentDateString]; 

NSLog(@"currentDateWithOffset: %@", currentDateWithOffset); // returns 2011-01-05 18:30:30 +0000 

Dank!

Edit:

Ich bin ein Verfahren in einer separaten Klasse aufrufen (versuchen, diese portable zu machen) mit der folgenden Zeile:

[Expiration expires:[[NSDate alloc] initWithString:@"2011-01-07 12:00:00 +0000"] within:1.0] 

in der Ablauf-Methode, habe ich diese Zeilen:

NSComparisonResult comparison = [currentDateWithOffset compare:expires]; // check for a fixed date to disable the demo 

double withinRange = [installDate timeIntervalSinceDate:currentDateWithOffset]; // check for number of seconds between "within" and the install date 

ich vergleiche dann diese beiden Werte in etwa so:

if(withinRange >= within && withinRange > 0.0) { 
    // app is expired // 
} 
else { 
    // app is still enabled (so far...) // 
    if(comparison == NSOrderedDescending || comparison == NSOrderedSame) { 
     // app is expired // 
    } 
    else { 
     // app is still enabled // 
    } 
} 

Hilft das? Danke für Ihre Geduld!

Edit:

Hier ist die gesamte gültig bis: in Verfahren, wie es derzeit steht ...

+(BOOL)expire:(NSDate*)expires within:(double)within { 
    // default expired value // 
    BOOL expired = NO; 

    // convert within value from days to seconds // 
    within *= 24.0 * 60.0 * 60.0; 

    // current date (gmt) // 
    NSDate *currentDate = [NSDate date]; 

    // install date // 
    NSDate *installDate = [[NSUserDefaults standardUserDefaults]objectForKey:@"installDate"]; 

    // check for a value in installDate // 
    if (nil == installDate) { 
     // app is running for the first time // 
     [[NSUserDefaults standardUserDefaults]setObject:currentDate forKey:@"installDate"]; 
     [[NSUserDefaults standardUserDefaults]synchronize]; 
     installDate = currentDate; 
    } 

    if([installDate timeIntervalSinceNow] < (-within)) { 
     expired = YES; 
    } 
    else { 
     if([expires timeIntervalSinceNow] < 0) { 
      expired = YES; 
     } 
    } 

    NSLog(@"installDate:%@", installDate); 
    NSLog(@"expires:%@", expires); 
    NSLog(@"currentDate:%@", currentDate); 

    return expired; 
} 

ich dann von einer anderen Klasse Aufruf mit

message.text = (YES == [Expiration expire:[[NSDate alloc] initWithString:@"2011-01-07 12:00:00 -0500"] within:(0.015625/2)]) ? @"This App is Expired" : @"This App is Active"; 

Beim Laufen Im Simulator (neue App-Installation) zeigte NSLog dies an ...

[Session started at 2011-01-06 10:43:46 -0500.] 
2011-01-06 10:43:48.146 TimeBasedDemo[14717:207] installDate:2011-01-06 15:43:48 +0000 
2011-01-06 10:43:48.147 TimeBasedDemo[14717:207] expires:2011-01-07 17:00:00 +0000 
2011-01-06 10:43:48.147 TimeBasedDemo[14717:207] currentDate:2011-01-06 15:43:48 +0000 
+0

Können Sie genauer sein, was ist es, was Sie eigentlich tun möchten? –

+0

Ich versuche, das aktuelle Datum/Uhrzeit mit einem angegebenen Datum/Uhrzeit für zeitlich begrenzte Demo-Apps zu vergleichen. Der Teil, der mir Ärger macht, ist der Vergleich in meiner Zeitzone (EST) statt in GMT. Einfacher, meine eigene Zeitzone zu verwenden, als in GMT zu konvertieren, wenn ich die containing-Methode aufruft. – Eric

+0

Dieser Code sieht genau richtig aus, und auch die Ausgabe. Ich nehme an, Ihr Problem ist, dass Sie erwartet haben, '10:43:48 -0500' im Log statt" 15:43:48 + 0000 "zu sehen. Die Sache ist - es ist in Ordnung. Sie sind * die gleiche Zeit *. So wird es ausgegeben, wenn Sie NSLog aufrufen. –

Antwort

5

Ein Objekt NSDate stellt einen Zeitpunkt unabhängig von Zeitzonen- und Kalenderüberlegungen dar. Zeitzoneninformationen sind relevant, wenn Sie ein Datum drucken oder analysieren, aber es wird nicht innerhalb der NSDate gespeichert.

Sagen Sie bitte Ihre Ablaufdatum wie folgt erstellen:

NSDate *exp=[[NSDate alloc] initWithString:@"2011-01-07 12:00:00 +0000"] 

Das sagt Ihnen der Ablauf mittags GMT stattfinden soll, am 7. Januar Wenn Sie es mittags EST ablaufen soll, erstellen Sie es mit -0500 stattdessen. Was Sie tun sollten ist nicht zu tun ist mit der aktuellen Zeit zu tun, wenn Sie einen Vergleich machen.

Eine nur einfache Möglichkeit, um zu sehen, wenn die Zeit dann

if ([exp timeIntervalSinceNow]<0) { /* it's expired */ } 

ist vergangen und man kann sehen, ob within Sekunden seit der Installation wie dieser Zeitpunkt bestanden haben:

if ([installDate timeIntervalSinceNow]<(-within)]) { /* it's expired */} 
+0

Hinzufügen zum ursprünglichen Beitrag, um den Code sauber zu halten ... – Eric

+0

Cool, ich habe meine Antwort aktualisiert –

+0

Danke, invariant! Das hat dazu beigetragen, die Dinge ein wenig zu säubern (und zu klären), danke. Leider habe ich immer noch ein Problem mit dem Zeitzonenproblem. installDate wird mithilfe von currentDate (NSDate * currentDate = [NSDate date];) festgelegt, sodass beim Vergleich weiterhin eine Diskrepanz auftritt. Da es das Ziel ist, die Klasse ohne Bearbeitung wiederzuverwenden und Zeitzonen-Offsets zuzulassen, ist NSDate der Weg dahin? – Eric

0

In Cocoa, NSDate ist eine abstrakte Darstellung eines Datums ohne Anwendung von Zeitzoneninformationen. Beachten Sie, dass currentDateWithOffset das gleiche Datum wie die Datumszeichenfolge ist, nur in einer anderen Zeitzone (fünf Stunden voraus). Dies ist das erwartete Verhalten, da NSDate nicht die Zeitzone beibehalten, die zum Erstellen verwendet wurde.

0

Ich bastelte etwas herum und fand einen Weg, um den Offset zu "schummeln", um meinen Bedürfnissen zu entsprechen. Aus anderen Lesung, ich vermute, dass NSCalendar könnte eine bessere langfristige-Lösung sein, aber jetzt kam ich

NSDate *currentDateWithOffset = [currentDateFormat dateFromString:currentDateString]; 

zu

NSDate *currentDateWithOffset = [[NSDate alloc] initWithString:[NSString stringWithFormat:@"%@ +0000", currentDateString]]; 

Wechsel auf, dass die Ergebnisse haben mich ich brauchte und Werke in den späteren Vergleichen verwende ich. Danke für die Hintergrundinformationen alle!

+0

Es wäre besser, wenn Sie sich die Mühe gemacht hätten, das Referenzdatum korrekt zu erstellen, dann hätten Sie nicht das aktuelle Datum wechseln müssen, um es zu bekommen arbeiten. –

+0

Ich werde versuchen, herauszufinden, wie das geht. – Eric

17

Keine dieser Antworten gab mir ein NSDate Objekt mit dem aktuellen, lokalen Datum. Also hier ist, wie ich es getan habe:

NSDate *currentDateWithOffset = [NSDate dateWithTimeIntervalSinceNow:[[NSTimeZone localTimeZone] secondsFromGMT]]; 
+0

Je vois ta tête partout! Danke für die Antwort! –

Verwandte Themen