22

Objective-C で iPhone アプリを作成すると、NSDateオブジェクトに解析する必要がある文字列形式 (UTC 形式で、末尾にゼロ UTC オフセットまたはズールー時間を示す Z が付いている) の日付があります。

ちょっとしたコード:

NSDateFormatter* df = [[NSDateFormatter alloc]init];
[df setDateFormat:@"yyyy-MM-dd'T'HH:mm:ss.SSSZ"];
NSString* str = @"2009-08-11T06:00:00.000Z";
NSDate* date = [df dateFromString:str];
これをデバッガーで実行すると、最終的にdatenil! 私はそれが私の日付フォーマット文字列と関係があると仮定しています。

日付文字列を正しく解析するにはどうすればよいですか?

考えられるのはZ、日付形式をリテラルにして、日付形式を に設定することyyyy-MM-dd'T'HH:mm:ss.SSS'Z'です。

Z がリテラルとして解析され、日付がオフセット情報を失い、あいまいになり、現地時間と解釈される場合を除いて、これはうまくいきます。

たとえば、解析する文字列が 2009-08-11T06:00:00.000Z (ズールー時間の 6:00) の場合、現地時間の 6:00 と解釈され、正しくないオフセットが適用されます。次に、ユーザーのオフセットに応じたオフセットで 2009-08-11T06:00:00.000-600 (ズールー時間の 12:00) として解析されます。

ありがとう!

4

7 に答える 7

28

私もこの問題を抱えていました.Appleのコード内のAPIバグなのか、それとも私の理解不足なのかはわかりませんが、日付文字列に時間オフセットを使用して回避しました.

例のコードを次のように変更した場合:

NSDateFormatter* df = [[NSDateFormatter alloc]init];
[df setDateFormat:@"yyyy-MM-dd'T'HH:mm:ss.SSSZ"];
NSString* str = @"2009-08-11T06:00:00.000-0700";   // NOTE -0700 is the only change
NSDate* date = [df dateFromString:str];

これで、日付文字列が解析されます。もちろん、-0700 時間は私のオフセットです。あなたの時間に変更する必要があります。お役に立てれば。

于 2009-08-12T00:34:14.603 に答える
13

ほとんどの回答では、「Z」をリテラル文字として扱うことをお勧めします。こんなことしないで!

Z は実際には、日付が 0 から UTC (+0000) までオフセットされていることを意味します。

これは、タイムゾーン形式ISO8601に従っています。

ISO 8601 タイム ゾーン形式: UTC 自体 ("Z") を除いて常に同じ形式を持つ、UTC からの一定の特定のオフセット。

"-08:00"

「ズ」

やりたいことは、NSDateFormatter に次の形式を使用することです。

 NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
                                  // 2013-11-18T23:00:00.324Z
                                  [formatter setTimeZone:[NSTimeZone localTimeZone]];
                                  [formatter setDateFormat:@"yyyy-MM-dd'T'HH:mm:ss.SSSZZZZZ"];
                                  return formatter;

Zを 5 回繰り返すことで、文字列の解析時に ISO8601 を使用するようフォーマッタに指示します。

ボーナス:

  • RFC 822 GMT 形式では、1 ~ 3 個のZを使用します。
  • ローカライズされた GMT 形式には 4 つのZを使用します。

詳細については、このドキュメントを確認してください。

于 2014-01-29T15:16:57.737 に答える
4

Z は実際にはフォーマッタにとって何かを意味し、代わりにリテラル文字を表す必要があるため、フォーマット文字列の Z を一重引用符で囲む必要があると思います。

    [df setDateFormat:@"yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"];
于 2009-08-12T08:21:08.250 に答える
2

文字列を操作する必要はありません。でタイムゾーンを設定するだけNSDateFormatterです(そして、そこにいるときのロケールも):

NSDateFormatter * formatter = [[NSDateFormatter alloc] init];
[formatter setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0]];
[formatter setLocale:[NSLocale systemLocale]];
[formatter setDateFormat:@"yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"];

必要に応じて日付文字列を解析します。

NSDate * value = [formatter dateFromString:@"2012-03-01T23:08:25.000Z"];
NSLog(@"%@", value); // prints 2012-03-01 23:08:25 +0000
于 2012-03-01T23:29:37.230 に答える
0

これはあなたを助けるかもしれません..「Z」はタイムゾーンコードのリテラルです。「o」(ゼロではなく文字)を使用してみてください。リテラル "o" は UTC オフセットを意味します。しばらく前にこれに遭遇しました。これがお役に立てば幸いです。

于 2009-11-21T20:31:27.887 に答える
-1
-(NSDate*)dateFromZulu:(NSString*)str {
    if (str == nil) {
        NSLog(@"Error getting date");
        return [NSDate date];
    }

    NSDateFormatter *f = [[NSDateFormatter alloc] init];
    [f setDateFormat:@"yyyy-MM-dd'T'HH:mm:ss Z"];
    NSDate *ret = [f dateFromString:[str stringByReplacingOccurrencesOfString:@"Z" withString:@" +0000"]];
    [f release];

    if (ret == nil) {
        ret = [NSDate date];
        NSLog(@"Error formatting date (%@)",str);       
    }   
    return ret;     
}
于 2010-04-30T20:21:35.547 に答える