NSDateFormatter возвращает нуль в ОС 4.0

У меня был следующий код, работающий на OS 3.x

NSString *stringDate = @"2010-06-21T20:06:36+00:00";
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:@"yyyy-MM-dd'T'HH:mm:ssZ"];
NSDate *theDate = [dateFormatter dateFromString:stringDate];
NSLog(@"%@",[dateFormatter stringFromDate:theDate]);

но теперь в новейшем xcode 3.2.3 под iOS4-симулятором varialble theDate равен нулю.

Я просмотрел ссылку на класс и не вижу ничего устаревшего или реализованного по-разному для iOS4 с помощью этих конкретных методов. Что я упустил?

Ответ 1

Я выяснил, что это работает, если вы делаете это так (см. ниже). Ключ использует метод: - [NSDateFormatter getObjectValue:forString:range:error:]

вместо

-[NSDateFormatter dateFromString]

Полный код:

+ (NSDate *)parseRFC3339Date:(NSString *)dateString 
{
    NSDateFormatter *rfc3339TimestampFormatterWithTimeZone = [[NSDateFormatter alloc] init];
    [rfc3339TimestampFormatterWithTimeZone setLocale:[[[NSLocale alloc] initWithLocaleIdentifier:@"en_US_POSIX"] autorelease]];
    [rfc3339TimestampFormatterWithTimeZone setDateFormat:@"yyyy-MM-dd'T'HH:mm:ssZ"];

    NSDate *theDate = nil;
    NSError *error = nil; 
    if (![rfc3339TimestampFormatterWithTimeZone getObjectValue:&theDate forString:dateString range:nil error:&error]) {
        NSLog(@"Date '%@' could not be parsed: %@", dateString, error);
    }

    [rfc3339TimestampFormatterWithTimeZone release];
    return theDate;
}

Ответ 2

Установлено ли ваше устройство на 24 часа или 12 часов?

Это звучит как безумный вопрос, но я просто столкнулся с этой ошибкой - формат даты изменит вашу строку формата в соответствии с текущей локалью, которая будет включать настройки формата времени.

Вы можете заставить его игнорировать их, добавив эту строку:

dateFormatter.locale = [[NSLocale alloc] initWithLocaleIdentifier:@"en_US_POSIX"];

Надеюсь, что это поможет.

Ответ 3

Этот код удалит дополнительный двоеточие, описанный AtomRiot:

Преобразование из:

  • NSString *stringDate = @"2010-06-21T20:06:36+00:00";

в

  • NSString *stringDate = @"2010-06-21T20:06:36+0000";
// Remove colon in timezone as iOS 4+ NSDateFormatter breaks
if (stringDate.length > 20) {
    stringDate = [stringDate stringByReplacingOccurrencesOfString:@":"
                                                       withString:@""
                                                          options:0
                                                            range:NSMakeRange(20, stringDate.length-20)];
}

для более подробной информации см.: https://devforums.apple.com/thread/45837

Ответ 4

Недавно я столкнулся с этой проблемой. Я закончил использование парсера Peter Hosey ISO8601. Он доступен здесь: http://boredzo.org/iso8601unparser/

Ответ 5

Кажется, что документация Apple, ну, "сложная":

Строка формата использует формат шаблонов из Unicode стандарта (эта ссылка относится к версии tr35-6для Mac OS X v10.5; для Mac OS X v10.4 используйте версию tr35-4).

и

iOS: режим совместимости v10.0 недоступен на iOS - только 10.4режим доступен.

В соответствии с версией tr35-4:

Используйте 1 для формата GMT, 2 для RFC 822

Z {1} GMT-08: 00
Z {2} -0800

Но в соответствии со стандартом Unicode:

Используйте одну-три буквы для RFC 822, четыре буквы для формата GMT.

Z {1,3} -0800
Z {4} GMT-08: 00

Итак, похоже, что iOS 4 использует tr35-6 - стандарт Unicode, поэтому +00: 00 теперь не работает против "Z".

Я пробовал -08: 00 против "ZZZZ" в моем NSDateFormatter, и он не удался в iOS 4. GMT-08: 00, однако, работал. Кажется, что часовой пояс (GMT) теперь требуется, а не факультативный, как это могло быть в iOS 3.

Ответ 6

Я получаю значение из dataFormat @"yyyy'-'MM'-'dd'T'HH':'mm':'ss'+'hh:mm";

Ответ 7

Формат, который мне предоставляется, находится на полпути между RFC 822 и GMT. если я изменил "+00: 00" на "+0000", тогда я могу использовать "Z" в своем формате. и если я изменю его на "GMT + 00: 00", то я смогу использовать ZZZZ для правильного получения данных. Кажется, что что-то было устранено, чтобы справиться с этим гибридом, поскольку он работал у меня раньше с OS 3.x.

Ответ 8

Выглядит хорошо для меня.

Он все еще функционирует правильно на реальном устройстве?

Если это так, сообщите об ошибке для симулятора, в противном случае укажите отчет об ошибке для iOS 4.

Ответ 9

Я просто отлаживал эту ту же проблему. У меня такая же строка даты, что и у 3.x, а не 4.0. Те же симптомы.

При просмотре документации NSDateFormatter я вижу:

Инициализация форматирования даты - init Доступен в iPhone OS 2.0 через iPhone OS 3.2

Это говорит о том, что метод init был устаревшим для iOS 4.0. Я не уверен, что это значит.

Ответ 10

Ссылка, опубликованная Elfred, сделала трюк. Я наткнулся на ту же проблему, конвертируя свое приложение из 3.1.3 в iOS4. Ссылка имеет класс ISO8601DateFormatter, который является гораздо более отличным расширением, чем мой собственный класс служебных данных.

Elfred писал (а): Недавно я столкнулся с этой проблемой. Я закончил использование парсера Peter Hosey ISO8601. Он доступен здесь: http://boredzo.org/iso8601unparser/

Ответ 11

Кажется, NSDateFormatter получил очень придирчивый.

-(void)dateFormatterTests {
    NSDateFormatter *formatter;

    formatter = [[NSDateFormatter alloc] init];

#ifdef WORKS
    [formatter setDateFormat:@"yyyy-MM-dd"];
#elif defined(ALSO_WORKS)
    [formatter setDateFormat:@"yyyy MM dd"];
    [formatter setLenient:YES];
#else // DOESN'T WORK
    [formatter setDateFormat:@"yyyy MM dd"];
#endif

    // Works per comments above
    NSLog(@"dFS: %@", [formatter dateFromString:@"2010-01-13"]);  
    // Never works with any of the above formats
    NSLog(@"dFS: %@", [formatter dateFromString:@"2010-01-13 22:00"]); 

    [formatter release]; formatter = nil;
}

Ответ 12

У меня была такая же проблема в моих приложениях, а Null Value из NSDateFormatter.

Я обнаружил, что моя проблема следующая:

Я отправил моему приложению дату и время следующим образом: 07/16/2010 04:21:00 +00:00 с форматом, подобным этому: [dateFormatter setDateFormat:@"MM/dd/yyyy HH:mm:ss ZZZ"]

Кажется, что часть ZZZ формирования NO LONGER принимает двоеточие: за время.

Работы: 07/16/2010 04:21:00 +0000

Не работает: 07/16/2010 04:21:00 +00:00

Чтобы поддерживать текущие приложения, которые были отключены, все, что я сделал, это поиск части +00:00 в строке и ее замена +0000.

Надеюсь, это поможет другим.

Ответ 13

Я использую его так же просто, как:

date_formatter = [[NSDateFormatter alloc] init];
        [date_formatter setDateStyle:NSDateFormatterShortStyle];
        [date_formatter setTimeStyle:NSDateFormatterNoStyle];

и это отлично работает. Я не понимаю, как они могут отказаться от метода init, когда класс NSDateFormatter подклассифицирован из NSObject