web-dev-qa-db-ja.com

iOSで日付文字列をNSDateオブジェクトに解析する方法は?

Xmlの日付文字列をiPhoneアプリのNSDateオブジェクトに解析しようとしています

これは以前に尋ねられたに違いないことを知っていますが、正しい構文を持っていると思いますが、機能していません。コードに問題はありますか?

解析する必要がある日付文字列は次のとおりです。

2011-01-21T12:26:47-05:00

解析に使用しているコードは次のとおりです。

self.dateFormatter = [[NSDateFormatter alloc] init];
    [self.dateFormatter setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0]];
    [self.dateFormatter setLocale:[[[NSLocale alloc] initWithLocaleIdentifier:@"en_US_POSIX"] autorelease]];
    [self.dateFormatter setDateFormat:@"yyyy'-'MM'-'dd'T'HH':'mm':'ss'Z'"];



... 

else if([elementName isEqualToString:kUpdated]){
    self.currentQuestion.updated = [self.dateFormatter dateFromString:self.currentParsedCharacterData ];
}

どんな助けも大歓迎です。ありがとう!

** ChrisKentからのリンク参照に基づいて、次のように問題を修正しました。

else if([elementName isEqualToString:kLastOnDeck]){

    NSString *dateStr = self.currentParsedCharacterData;
    // we need to strip out the single colon
    dateStr = [dateStr stringByReplacingOccurrencesOfString:@":" 
                                                 withString:@"" 
                                                    options:0 
                                                      range:NSMakeRange([dateStr length] - 5,5)];




    self.currentQuestion.lastOnDeck = [dateFormatter dateFromString:dateStr];

}
48
JohnRock

あなたが持っているほど多くの単一引用符は必要ありません(非日付/時刻文字でのみ必要です)ので、これを変更します:

[self.dateFormatter setDateFormat:@"yyyy'-'MM'-'dd'T'HH':'mm':'ss'Z'"];

これに:

[self.dateFormatter setDateFormat:@"yyyy-MM-dd'T'HH:mm:ssZZZ"];
...
self.currentQuestion.updated = [self.dateFormatter dateFromString:[self.currentParsedCharacterData stringByReplacingOccurrencesOfString:@":" withString:@"" options:0 range:NSMakeRange([self.currentParsedCharacterData length] – 5,5)]];

ここのドキュメント: https://developer.Apple.com/library/content/documentation/Cocoa/Conceptual/DataFormatting/Articles/dfDateFormatting10_4.html#//Apple_ref/doc/uid/TP40002369-SW1

Unicode形式パターン: http://unicode.org/reports/tr35/tr35-6.html#Date_Format_Patterns

コロンでタイムゾーンを扱う(+00:00): http://petersteinberger.com/2010/05/nsdateformatter-and-0000-parsing/

64
theChrisKent

これに対する簡単な答えを見つけるのに少し時間がかかりました。さらに、サードパーティのコードを追加する多くのソリューションがあります。

現在これに苦労しており、iOS 6以降のみをサポートしている人向け。

日付フォーマッターを設定できます

[dateFormatter setDateFormat:@"yyyy-MM-dd'T'HH:mm:ssZZZZZ"]

そして、これはコロンで「-05:00」を適切に処理します。

3
ucangetit

私は最後にコロンで同じ問題を抱えていました。これは、NSDateを幸せにするために日付を正規化するために使用した関数です。

/**
 * Timezones are returned to us in the format +nn:nn
 * The date formatter currently does not support IS 8601 dates, so
 * we convert timezone from the format "+07:30" to "+0730" (removing the colon) which
 * can then be parsed properly.
 */
- (NSString *)applyTimezoneFixForDate:(NSString *)date {
    NSRange colonRange = [date rangeOfCharacterFromSet:[NSCharacterSet characterSetWithCharactersInString:@":"] options:NSBackwardsSearch];
    return [date stringByReplacingCharactersInRange:colonRange withString:@""];
}
3
Anurag

ソリューションは変更することです:

[self.dateFormatter setDateFormat:@"yyyy'-'MM'-'dd'T'HH':'mm':'ss'Z'"];

この表記法:

[self.dateFormatter setDateFormat:@"yyyy-MM-dd'T'HH:mm:ss'Z'"];

私はそれがあなたを助けることを願っています。

1
Badre

問題は最後の「Z」です。引用符で囲んで記述する方法では、パーサーは時間文字列にリテラル文字Zを期待していますが、そうではありません。必要なのは、引用符なしのZフォーマット文字です。これは、タイムストリングにタイムゾーン情報が含まれていることを示します。これは、文字列の末尾の-05:00がタイムゾーンです。

タイムゾーン情報を期待しているため、日付フォーマッタでタイムゾーンを設定するのは無意味です。また、Unicodeのフォーマットパターンへのリンクを確認してください。このリンクには、ここで得られるすべての回答よりも信頼すべき決定的な情報が含まれています。

1
gnasher729

ISO8601DateFormatter

CocoaPodとして利用できるこのライブラリで大成功を収めました。

https://github.com/boredzo/iso-8601-date-formatter

使用法

- (ISO8601DateFormatter *)dateFormatter
{
    static ISO8601DateFormatter *dateFormatter = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        dateFormatter = [[ISO8601DateFormatter alloc] init];
        dateFormatter.includeTime = YES;
    });

    return dateFormatter;
}


NSDate *date = [[self dateFormatter] dateFromString:@"2015-05-09T13:06:00"];

IOS 10の時点で、提供されたシステム NSISO8601DateFormatter はこの特定の形式で利用可能です。

0
BergQuester