web-dev-qa-db-ja.com

タイムゾーンがNSDateに保存されないのはなぜですか?

Objective-cのNSStringからNSDateオブジェクトを初期化する必要があります。私はこのようにします:

NSString *dateString = [[webSentence child:@"DateTime"].text stringByReplacingOccurrencesOfString:@"T" withString:@" "];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:@"yyyy-mm-dd HH:mm:ss"];
[dateFormatter setTimeZone:[NSTimeZone timeZoneWithName:@"Europe/Budapest"]];

NSDate *date = [[NSDate alloc] init];
date = [dateFormatter dateFromString:dateString];

例:文字列値@ "2011-01-02 17:49:54"で試した場合、NSDate 2011-01-02 16:49:54 +0000が返されます。ご覧のとおり、2つの値の間には1時間の違いがあります。 NSDateの値が間違っています。これは、dateFormatterで設定したタイムゾーンの文字列で定義したものとまったく同じである必要があります。タイムゾーンを「ヨーロッパ/ブダペスト」に設定した場合でも、UTCとして定義された日付を使用しているようです。この問題を解決するにはどうすればよいですか?

ありがとう!

15
Tom

2つのこと:

1)日付形式の文字列にエラーがあります。 MMではなくmmを月に使用する必要があります(小文字のmmは分を表します)

2)NSDateオブジェクトを作成したら、NSDateFormatterメソッドを使用する必要がありますstringFromDate:特定のタイムゾーンにローカライズされた日付文字列を生成します。 NSDateオブジェクトに対してストレートNSLog()を実行すると、デフォルトで日付がGMTとして表示されます(GMTはブダペスト時間より1時間遅れています)

14
jonkroll

NSDateは、標準の参照日付に関連する日付を格納します。クラスのドキュメントから:

「NSDateの唯一のプリミティブメソッドであるtimeIntervalSinceReferenceDateは、NSDateインターフェイスの他のすべてのメソッドの基礎を提供します。このメソッドは、絶対参照日(2001年1月1日の最初の瞬間、GMT)を基準にした時間値を返します。」

NSDate自体には、タイムゾーンの概念はありません。したがって、NSDateFormatterは正しいことを行いました。これは、(タイムゾーンを指定することによって)GMTオフセットがあると伝えた日付を変換し、その日付の「正規化された」NSDateを提供します。

ヨーロッパ/ブダペストのタイムゾーンで表される日付を表示する場合は、既存の日付フォーマッター(-stringFromDate :)または適切なNSDate記述メソッド(例:-descriptionWithCalendarFormat:timeZone:locale :)を使用します。

追伸-書かれているように、コードにalloc/initはまったく必要ありません。非ARCでは、それはリークになります。

P.P.S.-日付の形式が正しくなく、無意味な結果になっています。私は先に進み、次のようにコードをクリーンアップしました(ARCでテスト済み):

NSString *dateString = @"2011-09-02 17:49:54";
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
NSTimeZone *tz = [NSTimeZone timeZoneWithName:@"Europe/Budapest"];
[dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
[dateFormatter setTimeZone:tz];

NSDate *date = [dateFormatter dateFromString:dateString];
NSLog(@"%@", [dateFormatter stringFromDate:date]);
NSLog(@"%@", [date descriptionWithCalendarFormat:nil timeZone:tz locale:nil]);
27
Conrad Shultz