NSDateFormatter, возвращающий ноль в OS 4.0 - PullRequest
26 голосов
/ 22 июня 2010

У меня был следующий код, работающий в 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 переменная theDate равна nil.

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

Ответы [ 13 ]

41 голосов
/ 19 октября 2010

Я обнаружил, что это работает, если вы делаете это таким образом (см. Ниже) Ключ использует метод: - [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;
}
8 голосов
/ 22 июня 2010

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

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

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

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

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

5 голосов
/ 21 августа 2010

Этот код удалит лишнее двоеточие, как описывает 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

2 голосов
/ 08 февраля 2011

Похоже, что документация 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.

2 голосов
/ 26 июня 2010

Я недавно столкнулся с этой проблемой. В итоге я использовал парсер Питера Хоси ISO8601 Это доступно здесь: http://boredzo.org/iso8601unparser/

1 голос
/ 09 июля 2010

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

1 голос
/ 26 июня 2010

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

0 голосов
/ 02 ноября 2010

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

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

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

0 голосов
/ 21 июля 2010

У меня была такая же проблема в моих приложениях Нулевое значение от NSDateFormatter .

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

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

Кажется, что ZZZ часть форматирования НИКОГДА больше не принимает двоеточие: во времени.

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

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

Для поддержки текущих приложений, которые я вышел, все, что я сделал, это поиск части +00:00 в строкеи замените его на +0000.

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

0 голосов
/ 11 июля 2010

Кажется, 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;
}
...