Диаграмма RFC3339 даты с NSDateFormatter в iOS 4.x и macOS X 10.6: невозможно?

StackOverflow https://stackoverflow.com/questions/4330137

Вопрос

Расположение даты RFC3339 с NSDateFormatter, по -видимому, невозможна в общем случае. Я ошибся? [Редактировать 2 года спустя: теперь есть способ! Смотрите ниже и сноску.

Не в значительной степени веб-сервис кормит мне даты, такие как:

2009-12-31T00:00:00-06:00

RFC3339, совместимый, вывод по умолчанию библиотеки JAXB, который они используют. Обратите внимание на толстую кишку, которая RFC3339 требует Когда смещение не буквально "Z":

time-numoffset  = ("+" / "-") time-hour ":" time-minute
time-offset     = "Z" / time-numoffset

Я хочу разобрать их в NSDATE.

NSDateFormatter хочет закономерности в синтаксисе, указанном Unicode, который предлагает символы поля даты для таких часовых поясов, как «PDT», «-0800», «GMT-08: 00», но не «-08: 00».

Googling и другие подобные вопросы, создают только форматы даты, такие как

[myDateParser setDateFormat:@"yyyy'-'MM'-'dd'T'HH':'mm':'ssZ"];
/* or: */ [myDateParser setDateFormat:@"yyyy'-'MM'-'dd'T'HH':'mm':'ss'Z'"];

Последнее из которых требует буквального «Z», а первое настаивает на отсутствии толстой кишки или присутствия «Гринвита». Тем не менее, они, по -видимому, работали до iOS 4.x (возможно, полностью отбрасывая смещение TZ; мои данные не ясны.)

Мои варианты на данный момент - это жалкое участие:

  • Откройте для себя какой -то нерекукументированный спецификатор формата или какой -то странный режим, чтобы поместить NSDateFormatter, который примет бездомную толстую кишку: Longshot, вероятно, отсутствует. [Сноска
  • Убедитесь, что мой издатель сервисов превратил все даты во время Zulu и указал «Z»: политически сложные.
  • Напишите мой собственный подкласс nsformatter или исследовать старый старый strptime_l: Работа. :)
  • Строка манипулирует моим входом и разделяет последний толстой кишки: хрупкий и уродливый, но вероятный путь наименьшего сопротивления.

Я точно понял ситуацию, что текущий NSDateFormatter следует строго без расширений Unicode; А форматы Unicode недостаточны для полного описания даты RFC3339?

Сноска Я возвращаюсь к этому три года спустя, чтобы забрать небольшое приложение: Unicode и Apple добавили эту функцию в строки формата, по состоянию на iOS6/OSX10.8. Сравнивать Последняя редакция на момент написания статьи с его непосредственный предшественник, и обратите внимание на добавление 5 "z", которое дает формат зоны, как "-08: 00". Так что, если вы можете уйти с помощью адаптации поддержки 5.x/10.7, есть новый правильный способ сделать это. Я оставлю предыдущий стенд ответа, так как это все еще лучший подход, когда требуется обратная совместимость.

Это было полезно?

Решение

Диаграмма строки даты в какао может быть болью, особенно если вам приходится иметь дело с датами, сгенерированными .NET на основе веб -сервисов.

Я бы посоветовал посмотреть на категорию NSDATE+InternetDateTime, которую Майкл Уотерфолл имеет на NSDATE в рамках своего проекта MWFeedParser на GitHub. Для меня это хорошо сработало, разрабатывая именно тот формат даты, который вы описываете.

https://github.com/mwaterfall/mwfeedparser/

Другие советы

- getObjectValue: ForString: Диапазон: Ошибка: может фактически разобрать RFC3339 Даты правильно. Я понятия не имею, почему - DateWithString: невозможно:

// RFC3339 date formatting
NSString *dateString = @"2012-04-11T18:34:19+00:00";
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
formatter.dateFormat = @"yyyy-MM-dd'T'HH:mm:ssZ";

NSDate *date;
NSError *error;
[formatter getObjectValue:&date forString:dateString range:nil error:&error];

Символы формата строк не задокументированы нигде в документации Apple. Вместо этого в некотором документе, указывающем на стандарт Unicode, есть ссылка, указывающая на стандарт Unicode

http://www.unicode.org/reports/tr35/tr35-31/tr35-dates.html#date_format_patterns

Использование информации по этой ссылке это довольно просто:

- (NSDate*)dateFromRFC3339String:(NSString*)aString
{
    static NSDateFormatter* sRFC3339DateFormatter = nil;
    static NSDateFormatter* sRFC3339DateFormatterSubSeconds = nil;
    static dispatch_once_t onceToken;

    dispatch_once(&onceToken, ^{
        NSLocale *enUSPOSIXLocale = [[NSLocale alloc] initWithLocaleIdentifier:@"en_US_POSIX"];

        sRFC3339DateFormatter = [[NSDateFormatter alloc] init];
        [sRFC3339DateFormatter setLocale:enUSPOSIXLocale];
        [sRFC3339DateFormatter setDateFormat:@"yyyy'-'MM'-'dd'T'HH':'mm':'ssXXXXX"];
        [sRFC3339DateFormatter setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0]];

        sRFC3339DateFormatterSubSeconds = [[NSDateFormatter alloc] init];
        [sRFC3339DateFormatterSubSeconds setLocale:enUSPOSIXLocale];
        [sRFC3339DateFormatterSubSeconds setDateFormat:@"yyyy'-'MM'-'dd'T'HH':'mm':'ss.SSSSSSXXXXX"];
        [sRFC3339DateFormatterSubSeconds setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0]];
    });

    NSDate* date = [sRFC3339DateFormatter dateFromString:aString];
    if (date == nil)
        date = [sRFC3339DateFormatterSubSeconds dateFromString:aString];

    return date;
}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top