Что случилось с тем, как я использую NSDateFormatter?

   NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
   dateFormatter.locale = [[[NSLocale alloc] initWithLocaleIdentifier:@"en_US"] autorelease];
   [dateFormatter setDateFormat:@"EEE, d MMM yyyy HH:mm:ss zzz"];
   NSString *dateString = @"Tue, 08 Jun 2010 17:00:00 EDT";
   NSDate *eventDate = [dateFormatter dateFromString:dateString];

В этом случае объект eventDate равен нулю. Может кто-нибудь подскажет мне? Этот код использовался для работы.

UPDATE: Невозможно говорить о том, почему это не работает из-за NDA. Достаточно сказать, что когда iOS 4 выйдет, я отправлю ответ на свой вопрос.

Ответы

Ответ 1

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

@"EEE, d MMM yyyy HH:mm:ss zzz"

когда это должно было быть:

@"EEE, dd MMM y HH:mm:ss zzz"

Часть iOS 4 и NDA заключалась в том, что я думал, что должен использовать метод NSDateFormatter dateFormatFromTemplate:options:locale:, который выглядел бы так:

NSString *format = [NSDateFormatter dateFormatFromTemplate:@"EEE, d MMM yyyy HH:mm:ss zzz" options:0 locale:[NSLocale currentLocale]];

Однако этот метод следует использовать только тогда, когда вы хотите отображать дату для пользователя неизвестной локали. В моем случае я точно знал, как будет выглядеть формат даты, и я пытался PARSE строку даты, чтобы я мог хранить ее в CoreData. Поэтому этот метод не был полезен.

Бонусная закладка: Прочитайте эту таблицу очень внимательно, и вы определенно выясните, в чем проблема... Форматы дат в формате Юникод должны соответствовать следующим спецификациям: http://unicode.org/reports/tr35/tr35-6.html#Date_Field_Symbol_Table

TL; DR Строка формата неверна. D'о!

Ответ 2

/*
    x           number
    xx          two digit number
    xxx         abbreviated name
    xxxx        full name

    a           AM/PM
    A           millisecond of day
    c           day of week (c,cc,ccc,cccc)
    d           day of month
    e           day of week (e,EEE,EEEE)
    F           week of month
    g           julian day (since 1/1/4713 BC)
    G           era designator (G=GGG,GGGG)
    h           hour (1-12, zero padded)
    H           hour (0-23, zero padded)
    L           month of year (L,LL,LLL,LLLL)
    m           minute of hour (0-59, zero padded)
    M           month of year (M,MM,MMM,MMMM)
    Q           quarter of year (Q,QQ,QQQ,QQQQ)
    s           seconds of minute (0-59, zero padded)
    S           fraction of second
    u           zero padded year
    v           general timezone (v=vvv,vvvv)
    w           week of year (0-53, zero padded)
    y           year (y,yy,yyyy)
    z           specific timezone (z=zzz,zzzz)
    Z           timezone offset +0000

    sql         y-M-d H:m:s
    rss         [E, ]d MMM y[y] H:m:s Z|z[zzz]
*/

Это мой комментарий для синтаксического анализа даты. Я использую следующее, где toDateUsingFormat использует NSDateFormatter с переданной в строке. Я не использую локаль, потому что даты rss не локализованы.

    if ( 0 == [string rangeOfString:@","].length ) {
        result = [string toDateUsingFormat:@"d MMM y H:m:s z"];
    } else {
        result = [string toDateUsingFormat:@"E, d MMM y H:m:s z"];
    }

Edit:

Я использую getObjectValue: вместо dateFromString.

NSDate *result = nil;
NSError *error = nil;
[dataFormatter getObjectValue:&result forString:dateString errorDescription:&error];

Ответ 3

Полный список спецификаторов формата UTS # 35. Форматы формата даты.

Используется ли символ "c" вместо "E"? Документ имеет очень близкую альтернативу и может привести к желаемому результату.

(Если вам действительно нужны символы в строке формата, которых нет в таблице, вы можете избежать их, например hh 'o''clock' a, zzzz - создает формат, например "12 часов PM, Pacific Daylight Time".)

Ответ 4

Проблема, которую я обнаружил, состоит в том, что строка, которую я обрабатывал, имеет некоторые завершающие символы "\n\t\t". Решение заключалось в их удалении:

[string stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];

Ответ 5

у вас есть нулевой проложенный день, а именно 08 в вашей строке даты, однако в вашей строке формата формат пытается проанализировать ненулевой заполненный день, а именно d. изменение d до dd должно устранить проблему