2011-01-05 4 views
7

Je dois manquer quelque chose de petite mais je n'arrive pas à comprendre. Essayer de créer une date de comparaison, mais je ne peux pas sembler compenser currentDate de GMT à EST:NSDate - Décalage du fuseau horaire

// 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 

Merci!

Edit:

J'appelle une méthode dans une classe séparée (en essayant de faire ce portable) en utilisant la ligne suivante:

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

dans la méthode arrive à expiration, j'ai ces lignes:

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 

Je puis on compare ces deux valeurs comme ceci:

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 // 
    } 
} 

Est-ce que cela aide? Merci pour votre patience!

Edit:

est ici l'ensemble arrive à expiration: au sein de la méthode telle qu'elle est actuellement ...

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

je puis l'appeler d'une autre classe avec

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"; 

Lors de l'exécution dans le simulateur (installation d'application fraîche), NSLog a affiché ce ...

[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

Pouvez-vous être plus précis sur ce que vous voulez vraiment faire? –

+0

J'essaie de comparer la date et l'heure actuelles avec une date/heure fournie pour les applications de démonstration limitées dans le temps. La partie qui me donne la peine de faire la comparaison dans mon fuseau horaire (EST) plutôt que GMT. Plus facile d'utiliser mon propre fuseau horaire que de convertir en GMT lorsque j'appelle la méthode contenant. – Eric

+0

Ce code semble parfaitement correct, tout comme la sortie. Je suppose que votre problème est que vous vous attendiez à voir '10:43:48 -0500' dans le journal plutôt que' 15:43:48 + 0000'. La chose est - c'est OK. Ils sont * en même temps *. C'est exactement comme cela que vous imprimez lorsque vous appelez NSLog. –

Répondre

5

Un objet NSDate représente un instant dans le temps, indépendamment des considérations de fuseau horaire et de calendrier. L'information de fuseau horaire est pertinente lorsque vous imprimez ou analysez une date, mais elle n'est pas stockée dans le NSDate.

Dites que vous créez votre date d'expiration comme ceci:

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

qui dit que vous voulez l'expiration de se produire à midi GMT, le 7 si vous voulez expirer à midi HNE, créez avec -0500 à la place. Ce que vous devez faire, c'est et non c'est de jouer avec l'heure actuelle quand vous faites une comparaison.

Un moyen facile juste pour voir si le temps est écoulé est alors

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

et vous pouvez voir si within secondes se sont écoulées depuis la date d'installation comme ceci:

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

Ajout à la publication originale pour garder le code propre ... – Eric

+0

Cool, j'ai mis à jour ma réponse –

+0

Merci, invariant! Cela a aidé à nettoyer (et effacer) les choses un peu, merci. Malheureusement, j'ai toujours un problème avec le problème de fuseau horaire. Le paramètre installDate est défini à l'aide de currentDate (NSDate * currentDate = [date NSDate];), de sorte qu'il y a toujours un écart lors de la comparaison. Puisque le but est de réutiliser la classe sans la modifier, et de permettre les décalages de fuseau horaire, NSDate est-il le moyen d'aller avec cela? – Eric

0

En Cocoa, NSDate est une représentation abstraite d'une date sans information de fuseau horaire appliquée. Notez que currentDateWithOffsetest la même date que la chaîne de date, juste dans un fuseau horaire différent (cinq heures d'avance). Ce comportement est attendu car NSDate ne persiste pas dans le fuseau horaire utilisé pour le créer.

0

J'ai bricolé un peu plus et trouvé un moyen de «tricher» l'offset pour répondre à mes besoins. De l'autre lecture, je suppose que NSCalendar pourrait être une meilleure solution à long terme, mais pour l'instant je fini par changer

NSDate *currentDateWithOffset = [currentDateFormat dateFromString:currentDateString]; 

à

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

Cela m'a obtenu les résultats que je avais besoin et travaux dans les comparaisons ultérieures que j'utilise. Merci pour l'info de fond tous!

+0

Vous feriez mieux d'avoir mis l'effort dedans pour créer la date de référence correctement, alors vous n'auriez pas dû swizzle la date actuelle pour l'obtenir travailler. –

+0

Je vais essayer de comprendre comment faire cela. – Eric

17

Aucune de ces réponses ne m'a donné un objet NSDate avec la date locale actuelle. Alors, voici comment je l'ai fait:

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

Je vois ta tête partout! Merci d'avoir répondu! –

Questions connexes