web-dev-qa-db-ja.com

タイムゾーンで調整されたNSDateからNSDateを取得します

NSDateオブジェクトがあります。 「2011年1月10日」を表すとしましょう

NSDate *date = [df dateFromString:@"2011-10-01 00:00:00"];

その日付は、私のタイムゾーンのために「2011-09-3022:00:00」に変換されます。

質問:ローカルタイムゾーンで「2011-10-0100:00:00」を表す新しいDateオブジェクトを取得するにはどうすればよいですか?

16
Tycho Pandelaar

NSDateは、絶対時点のみを表します。タイムゾーンやカレンダーの概念はありません。 NSDateインスタンスを作成すると、2001年1月1日GMTからわずか数秒になります。ニューヨーク、東京、バルセロナ、エルサレムのどこにいても構いません。

あなたの例では、GMTに基づいてNSDateをインスタンス化しますが、[date description]NSLogで使用)はそれを現地時間に変換します。そこにミスマッチがあります。

したがって、考慮すべき2つの部分があります。

1.NSCalendarとNSTimeZoneを使用したNSDateの作成

手動で日付を作成する場合は、カレンダー(グレゴリオ暦では2012年、ヘブライ語では5772)とタイムゾーン(ロンドン時間の午後22時、シドニー時間の午前7時)を指定する必要があります。

// Use the user's current calendar and time zone
NSCalendar *calendar = [NSCalendar currentCalendar];
[calendar setTimeZone: [NSTimeZone systemTimeZone]];

// Specify the date components manually (year, month, day, hour, minutes, etc.)
NSDateComponents *timeZoneComps=[[NSDateComponents alloc] init];
[timeZoneComps setHour:22];
[timeZoneComps setMinute:0];
[timeZoneComps setSecond:0];
// ... year, month, ...

// transform the date compoments into a date, based on current calendar settings
NSDate *date = [calendar dateFromComponents:timeZoneComps];

この時点で、日付は現在のカレンダーを表す正確な時点(秒単位)を格納します。

2.NSDateFormatterを使用したNSDate出力

NSDateの制御された出力には、NSDateFormatterが必要です。これは使用されます日付を文字列に変換します。

Apple NSDateFormatterクラスリファレンス ドキュメントに基づく

スタイルの日付フォーマッターで取得および設定できる属性は多数ありますが、...ただし、個々の設定を変更しないでください。代わりに、初期化時に確立されたデフォルト設定を受け入れ、setDateStyle:、setTimeStyle:を使用して形式を指定する必要があります。

これは、ロケールごとに異なる出力にとって特に重要です。デフォルトでは、NSDateFormatterは現在のユーザーのロケール設定を監視します。したがって、同じNSDateは22.11.2011 18:33:19、またはNov 22, 2011 6:33:19 PM、または2011-11-22 下午6:33:19 あるいは २२-११-२०११ ६:३३:१९ अपराह्、すべて同じ入力と同じコード。

そしてコード:

//  NSDate *date -> NSString *dateString 

NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateStyle:NSDateFormatterMediumStyle];
[dateFormatter setTimeStyle:NSDateFormatterShortStyle];

// Medium style date, short style time => "Nov 23, 1937 3:30pm"
NSString *dateString = [dateFormatter stringFromDate:date];

または、クラスメソッドを使用して変換することもできます localizedStringFromDate:dateStyle:timeStyle:

これで問題が明らかになることを願っています。

30

[NSDate date]はGMTで日付を返します。

あなたが述べるとき:

その日付は、私のタイムゾーンのために「2011-09-3022:00:00」に変換されます。

それはNSLogまたはNSDateFormatterからですか? NSLogが使用する[date description]に依存しないでください。ローカルタイムゾーンが考慮され、NSDateFormatterを使用します。 NSDateFormatterにはsetTimeZoneメソッドがあります。

From Apple [date description]のドキュメント:

この表現は、オペレーティングシステムのさまざまなリリース間で一定であることが保証されていません。日付をフォーマットするには、代わりに日付フォーマッターオブジェクトを使用する必要があります

6
zaph