Есть ли простой способ преобразования метки времени ISO8601 в форматированную дату NSD? - PullRequest
46 голосов
/ 04 февраля 2010

Если я использую следующий код:

NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];   
[dateFormatter setDateFormat:@"yyyy-MM-dd'T'HH:mm"];
NSDate *myDate = [dateFormatter dateFromString:@"2010-01-28T15:22:23.863"];
NSLog(@"%@", [dateFormatter stringFromDate:myDate]);

Он успешно преобразован в Date объект, однако я не могу отформатировать его каким-либо иным способом, кроме yyyy-MM-dd'T'HH:mm, то есть регистрируется 2010-01-28T15:22:23

Если я изменю dateFormat на [dateFormatter setDateFormat:@"yyyy-MMMM-d'T'HH:mm"];, объект Date будет нулевым ...

Итак, мой последний вопрос - как отформатировать метку времени ISO8601 из базы данных SQL, чтобы использовать, например, NSDateFormatterMediumStyle для возврата «1 января 2010 года»?

Ответы [ 8 ]

42 голосов
/ 08 июля 2010

У меня похожая, но немного более сложная проблема, и я нашел очень простое решение!

Проблема: Мои входящие даты ISO8601 выглядят так: 2006-06-14T11:06:00+02:00 Онииметь смещение часового пояса в конце.

Решение: Использовать ISO8601DateFormatter Питера Хоси , который можно загрузить с здесь .

ISO8601DateFormatter *formatter = [[ISO8601DateFormatter alloc] init];
NSDate *theDate = [formatter dateFromString:dateString];
[formatter release], formatter = nil;

и

ISO8601DateFormatter *formatter = [[ISO8601DateFormatter alloc] init];
NSString *dateString = [formatter stringFromDate:[twitch dateTwitched]];
[formatter release], formatter = nil;
19 голосов
/ 24 сентября 2012

Вот пример кода от яблока

    NSDateFormatter * formatter = [[NSDateFormatter alloc] init];
    [formatter setDateFormat:@"yyyy'-'MM'-'dd'T'HH':'mm':'ss'Z'"];
    NSDate *date = [formatter dateFromString:dateString];

ссылка: https://developer.apple.com/library/ios/#qa/qa1480/_index.html

19 голосов
/ 04 февраля 2010

Вам нужен другой форматер для обработки вывода. Поставьте это после вашего кода:

NSDateFormatter *anotherDateFormatter = [[NSDateFormatter alloc] init];   
[anotherDateFormatter setDateStyle:NSDateFormatterLongStyle];
[anotherDateFormatter setTimeStyle:NSDateFormatterShortStyle];
NSLog(@"%@", [anotherDateFormatter stringFromDate:myDate]);
12 голосов
/ 28 июня 2013

Сразу отметим, что начиная с iOS 6.0 вы можете использовать этот формат:

 yyyy-MM-dd'T'HH:mm:ssZZZZZ
6 голосов
/ 24 августа 2013

У меня очень быстрая реализация C синтаксического анализа строк NSString ISO8601 в NSDates в SAMCategories . Вы можете установить его с CocoaPods или просто скопировать файлы в ваш проект.

Вот как это использовать:

[NSDate sam_dateFromISO8601String:@"2013-08-24T06:51:21-07:00"]

Это очень надежно и поддерживает пропущенные часовые пояса и т. Д. Как и В моем комментарии выше сказано, что NSDateFormatter был очень медленным для меня при анализе большого количества дат. Переход на эту реализацию помог огромному количеству.

Этот код используется в 6 производственных приложениях (включая Hipstamatic и Roon ), над которыми я работал без известных проблем. Существует набор тестов для предотвращения регрессии.

Короче говоря, я думаю, что это лучший способ анализа строк ISO8601 в Objective-C.


Если коротко, если вы беспокоитесь о производительности и передаче, отправка целых чисел вместо строк ISO8601 очень предпочтительна. Вы можете просто конвертировать их в даты с [NSDate dateWithTimeIntervalSince1970:yourInteger]. Быстродействие настолько быстрое, насколько вы можете его достичь, и по проводам передается меньше символов.

5 голосов
/ 05 февраля 2010

Я должен отметить, что в прошлый раз, когда я проверял методы Apple NSDate, не поддерживали ISO8601. У меня все еще есть ошибка в Apple по поводу официальной поддержки.

+ (id)dateWithNaturalLanguageString:(NSString *)string

будет правильно (в прошлый раз, когда я его запускал) проанализировать и создать объект NSDate из строки ISO801, хотя в документации сказано, что вы не должны его использовать, он работал на всех датах ISO8601, которые я пробовал до сих пор.

3 голосов
/ 08 июля 2014

@ danielbeard ответ работал для меня. Однако вам нужно включить часовой пояс, иначе он преобразует дату UTC в ваш текущий часовой пояс, а это не то, что вам нужно.

- (NSDate *) dateFromISO8601DateString:(NSString *) dateString {
    NSDateFormatter * dateFormatter = [NSDateFormatter new];
    dateFormatter.timeZone = [NSTimeZone timeZoneWithName:@"UTC"];
    [dateFormatter setDateFormat:@"yyyy'-'MM'-'dd'T'HH':'mm':'ss'Z'"];
    NSDate * date = [dateFormatter dateFromString:dateString];
    return date;
}
2 голосов
/ 18 октября 2015

@ Нить капитан Попробуйте этот формат: "гггг-ММ-дд'ТХЧ: мм: сс.ССС"

...