2011-01-05 7 views
7

Должно быть, мне не хватает чего-то маленького, но не могу понять. Попытка создать дату для сравнения, но я не могу показаться, чтобы компенсировать CurrentDate от GMT к EST:NSDate - Смещение часового пояса

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

Спасибо!

Edit:

Я звоню метод в отдельный класс (пытается сделать этот портативный), используя следующую строку:

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

в истекает метод, у меня есть следующие строки:

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 

Я тогда, сравнивая эти два значения, как так:

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

Помогает ли это? Спасибо за ваше терпение!

Edit:

Вот весь Expires: в методе, как это в настоящее время стоит ...

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

Я затем вызвать его из другого класса с

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

При запуске в симуляторе (новая установка приложения), NSLog показал это ...

[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

Можете ли вы уточнить, что именно вы на самом деле хотите сделать? –

+0

Я пытаюсь сравнить текущую дату/время с предоставленной датой/временем для демонстрационных приложений с ограниченным временем. Часть, которая дает мне хлопот, делает сравнение в моем часовом поясе (EST), а не в GMT. Легче использовать мой собственный часовой пояс, чем конвертировать в GMT, когда я вызываю метод-содержащий. – Eric

+0

Этот код выглядит точно так же, как и выход. Я предполагаю, что ваша проблема в том, что вы ожидали увидеть '10:43:48 -0500' в журнале, а не' 15:43:48 + 0000'. Дело в том, что все в порядке. Они * одновременно *. Именно так оно печатается при вызове NSLog. –

ответ

5

Объект NSDate представляет собой мгновенное время независимо от часового пояса и соображений календаря. Информация о часовом поясе актуальна, когда вы печатаете или разбираете дату, но она не сохраняется в пределахNSDate.

Допустим, вы создаете свою дату истечения срока действия, как это:

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

Это говорит, что вы хотите, истечение произойти в полдень по Гринвичу, на 7 января Если вы хотите, чтобы он истекает в полдень EST, создать его вместо -0500. То, что вы должны не, должно быть связано с текущим временем, когда вы проводите сравнение.

Простой способ просто увидеть, если время прошло тогда

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

, и вы можете увидеть, если within секунд прошло с момента установки, как это:

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

Добавляем к исходному сообщению, чтобы код был чистым ... – Eric

+0

Прохладный, я обновил свой ответ –

+0

Спасибо, инвариант! Спасибо, что помогло очистить (и очистить) вещи. К сожалению, у меня все еще проблема с часовым поясом. installDate устанавливается с использованием currentDate (NSDate * currentDate = [NSDate date];), поэтому во время сравнения все еще существует несоответствие. Поскольку цель состоит в том, чтобы повторно использовать класс без редактирования и разрешить смещения часового пояса, является ли NSDate способ действительно идти с этим? – Eric

0

В какао, NSDate - это абстрактное представление даты без использования информации о часовом поясе. Обратите внимание, что currentDateWithOffset- в тот же день, что и строка даты, только в другом часовом поясе (на пять часов вперед). Это ожидаемое поведение, так как NSDate не поддерживает часовой пояс, используемый для его создания.

0

Я немного потрудился и нашел способ «обмануть» смещение в соответствии с моими потребностями. С другой чтения, я предполагаю, что NSCalendar может быть лучше Долгосрочное решение, но сейчас я в конечном итоге изменить

NSDate *currentDateWithOffset = [currentDateFormat dateFromString:currentDateString]; 

в

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

Это заставил меня результаты мне нужно и работу в последующих сравнениях, которые я использую. Спасибо за справочную информацию все!

+0

Вам было бы лучше приложить усилия для создания контрольной даты правильно, тогда вам не пришлось бы swizzle текущей даты, чтобы получить его работать. –

+0

Я постараюсь выяснить, как это сделать. – Eric

17

Ни один из этих ответов не дал мне NSDate объект с текущей, местной датой. Итак, вот как я это сделал:

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

Je vois ta tête partout! Спасибо за ответ! –

Смежные вопросы