6

この種の質問がたくさんあることは知っていますが、私の場合の解決策は見つかりませんでした。ではなく、現在の正しいNSDateオブジェクトを取得する必要がありますNSString。私はウクライナ出身なので、このコードは間違った時刻 (+3 時間) を返します。

NSDate *currentDate = [NSDate date];

から現在のNSDateオブジェクトを取得する方法はNSDateFormatter? の入手方法しか知らないがNSString、必要ない。

編集:私はこのコードを使用して、オブジェクトNSDatesを使用して 2 を比較しています。ここにコードがあります:NSCalendar

NSCalendar *calendar = [NSCalendar currentCalendar];
NSUInteger unitFlags = NSDayCalendarUnit | NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit;
NSDateComponents *components = [calendar components:unitFlags fromDate:nowDate toDate:endDate options:0];

components.hour+3時間の差を示しています

4

3 に答える 3

9

NSDates は常に UTC で保存されます。実際には、日付自体はタイムゾーンや週、月、年について何も知りません。それらはある時点にすぎません。

地球上の位置の正確な時間を確認するには、時間モデルを表す NSCalendar を考慮する必要があります。それを直接使用して日付をいじったり、日付をそのままにしてニーズに合わせて外観を調整する NSDateFormatter を作成したりできます。

NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateStyle:NSDateFormatterFullStyle];
[formatter setTimeStyle:NSDateFormatterFullStyle];

NSLog(@"%@", [formatter stringFromDate: date1]);

結果は

Thursday, July 12, 2012, 4:36:07 PM Central European Summer Time 

コメントに応えて:

このコードをテストとして試してください

NSDate *now = [NSDate date];
NSDate *startOfToday = nil;
NSDate *startOfThisWeek = nil;
NSDate *startOfThisMonth = nil;
NSDate *startOfThisYear = nil;
[[NSCalendar currentCalendar] rangeOfUnit:NSDayCalendarUnit startDate:&startOfToday interval:NULL forDate:now];
[[NSCalendar currentCalendar] rangeOfUnit:NSWeekCalendarUnit startDate:&startOfThisWeek interval:NULL forDate:now];
[[NSCalendar currentCalendar] rangeOfUnit:NSMonthCalendarUnit startDate:&startOfThisMonth interval:NULL forDate:now];
[[NSCalendar currentCalendar] rangeOfUnit:NSYearCalendarUnit startDate:&startOfThisYear interval:NULL forDate:now];

NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateStyle:NSDateFormatterFullStyle];
[formatter setTimeStyle:NSDateFormatterFullStyle];

NSLog(@"%@", now);
NSLog(@"%@", [formatter stringFromDate:now]);

NSLog(@"%@", startOfToday);
NSLog(@"%@", [formatter stringFromDate:startOfToday]);

NSLog(@"%@", startOfThisWeek);
NSLog(@"%@", [formatter stringFromDate:startOfThisWeek]);

NSLog(@"%@", startOfThisMonth);
NSLog(@"%@", [formatter stringFromDate:startOfThisMonth]);

NSLog(@"%@", startOfThisYear);
NSLog(@"%@", [formatter stringFromDate:startOfThisYear]);

各 NSLog ペアの最初の日付は UTC で、2 番目の日付はローカル タイム ゾーンで提供されるため、日、週、月、年の開始は現地時間に調整されることに気付くでしょう。


このコードを投稿したチャットで

NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init]; 
[dateFormat setDateFormat:@"yyyy-MM-dd HH:mm"]; 
[dateFormat setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0]]; 
NSDate *date = [dateFormat dateFromString:dateString]; 
[dateFormat release]; 

問題は、日付文字列が実際には GMT ではなく、EET (東ヨーロッパ時間) からのものであることです。

試す

[dateFormat setTimeZone:[NSTimeZone timeZoneWithAbbreviation:@"EET"]]; 

2012-07-12 12:23:00 +0300しかし、はるかに洗練された解決策は、可能な場合と同様に、UTC へのオフセットを使用して日付文字列を取得することです。
このような場合
[dateFormat setDateFormat:@"yyyy-mm-dd HH:mm:ss Z"]; 、フォーマッタは -specifier を介してオフセットを認識しているため、それを解析することができ、それ以上のタイム ゾーン処理は必要ありませんZ
また、タイムゾーンを設定しない場合は、デバイスの現在の時刻を使用する必要があることに注意してください。ユーザーが常に日付文字列の時間と同じタイムゾーンにいる場合、これも機能するはずです。しかし、ユーザーがそのゾーンを離れた場合、または世界中で動作するようにしたい場合は、私が提供したソリューションのいずれかを使用する必要があります. 2 番目 (日付文字列内でタイムゾーンを指定) が優先されます。

于 2012-07-12T15:03:35.390 に答える
2

日付はおそらく正しい値です。ログに記録すると間違っているように見えるので、おそらく間違っていると思いますか?これは、ログに記録すると、日付が UTC で表示されるためです。NSDateFormatter を使用して、ローカル タイムゾーンで文字列を取得できます。

于 2012-07-12T14:48:30.180 に答える
2

2 番目の日付が UTC の場合、正解です。ウクライナは現在 UTC より 3 時間進んでいるため、UTC の真夜中はウクライナでは 21:00 です。21:00~18:00の3時間です。したがって、2番目の日付を取得する方法を確認してください. 間違ったタイム ゾーンが指定されている可能性があります。

最初の日付が実際にウクライナ時間の 18:00 に作成された場合

nowDate = [NSDate date];

その場合、2 番目の日付は実際には UTC の午前 0 時に対応するウクライナ時間の 21:00 です。真夜中だと主張しているので、暗黙的または明示的に UTC を使用して文字列から作成したに違いありません。どのように作成したかを見せてください。

** 編集 **

チャットで教えてくれたコードは次のとおりです。

NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init]; 
[dateFormat setDateFormat:@"yyyy-MM-dd HH:mm"]; 
[dateFormat setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0]]; 
NSDate *date = [dateFormat dateFromString:dateString]; 
[dateFormat release]; 

3 行目では、タイム ゾーンを GMT に設定します。これは、すべての意図と目的で UTC と同じです。日付フォーマッタはおそらくデバイスの正しいロケールに初期化されているため、おそらくその行を省略できます。

于 2012-07-12T15:14:09.953 に答える