web-dev-qa-db-ja.com

ISO8601タイムスタンプをフォーマットされたNSDateに変換する簡単な方法はありますか?

次のコードを使用した場合:

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オブジェクトがnullになります...

したがって、私の最終的な質問は、SQLデータベースからISO8601タイムスタンプをフォーマットして、たとえばNSDateFormatterMediumStyleを使用して「2010年1月1日」を返す方法です。

46
rson

出力を処理するには、別のフォーマッターが必要です。これをあなたのコードの後に​​置きます:

NSDateFormatter *anotherDateFormatter = [[NSDateFormatter alloc] init];   
[anotherDateFormatter setDateStyle:NSDateFormatterLongStyle];
[anotherDateFormatter setTimeStyle:NSDateFormatterShortStyle];
NSLog(@"%@", [anotherDateFormatter stringFromDate:myDate]);
19
osteven

似ていますが、少し複雑な問題があり、非常に単純な解決策を見つけました!

問題:着信ISO8601の日付は次のようになります:2006-06-14T11:06:00+02:00最後にタイムゾーンオフセットがあります。

解決策:からダウンロードできるPeter Hoseyの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;
42
Matthew

こちらがアップルのサンプルコードです

    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
david

IOS 6.0以降では、次の形式を使用できることに注意してください。

 yyyy-MM-dd'T'HH:mm:ssZZZZZ
12
Marcin

SAMCategories で、ISO8601 NSStringをNSDatesに解析する非常に高速なC実装があります。 CocoaPodsを使用してインストールするか、ファイルをプロジェクトにコピーするだけです。

使用方法は次のとおりです。

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

これは非常に堅牢で、欠落しているタイムゾーンなどをサポートします。 上記の私のコメント のように、多くの日付を解析するとき、NSDateFormatterは非常に遅くなりました。この実装への切り替えは、莫大な量の助けとなりました。

このコードは、既知の問題なしに取り組んだ6つのプロダクションアプリ(Hipstamaticおよび Roon を含む)で使用されています。退行を防ぐために test suite があります。

要するに、これはObjective-CでISO8601文字列を解析する最良の方法だと思います。


余談ですが、パフォーマンスと転送が心配な場合は、ISO8601文字列の代わりに整数を送信することをお勧めします。 [NSDate dateWithTimeIntervalSince1970:yourInteger]を使用して、単純に日付に変換できます。パフォーマンスはあなたがそれを作ることができるのと同じくらい速いです、そして、有線で転送するより少ない文字があります。

6
Sam Soffes

前回Apples NSDateメソッドをチェックしたとき、ISO8601をサポートしていなかったことに注意してください。私はまだAppleにバグがあり、公式サポートを提供することに関してはまだです。

+ (id)dateWithNaturalLanguageString:(NSString *)string

iSO801文字列からNSDateオブジェクトを適切に(前回実行したときに)解析して作成しますが、ドキュメントでは使用しないでくださいと記載していますが、これまでに試したISO8601のすべての日付で機能します。

5
Colin Wheeler

@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;
}
3
gngrwzrd

@Thread captainこのフォーマットを試してください: "yyyy-MM-dd'T'HH:mm:ss.SSS"

2
Andi Utzinger