0

編集:私の解決策は以下です。

ユーザーが特定の整数の日数を前後にジャンプできる、一種のカレンダー関連のアプリがあります。真夜中頃にアプリをテストしたところ、DST 関連の問題があることに気付き、最善の解決策を探していました。

このアプリは、iOS のどのカレンダーにも実際には基づいていません。ただし、グレゴリオ暦の日付と時刻を表示するので、ユーザーはおなじみの日付と時刻を参照できます。

ビルトイン ジャンプの 1 つは 73 日で、これは約 1/5 年です。使用される一般的な日付は、3 月分 +/- 73 日の整数倍です。たとえば、3 月の春分点から 73 日前の日付にジャンプする場合に問題が発生します。システムのタイムゾーン設定によって異なります。ただし、アプリはタイムゾーンとは何の関係もないため、DST などがないかのように時間を表示したいのですが、それでもローカル タイムゾーンを使用しています。それが理にかなっていることを願っています。

これを達成する方法について何か提案はありますか? 質問があいまいすぎる場合は、詳細を追加できるかもしれませんが、追加しすぎて混乱させたくありません。

編集: 何が起こっているかを説明するために、アプリからのサンプル スクリーン プリントをリンクすることにしました。この写真: http://victorspictures.com/trollart/h37a90c77#h56122c20 は、今年の春分の構成を示しています。キャプションは、デバイスの読み方を説明しています。ギャラリーの次の 2 つの写真に従って、デバイスを使用してイースターの日付を計算する方法を確認してください。

いずれにせよ、スワイプ ジェスチャでは、ユーザーが +/- 1 日または +/- 73 日移動できるため、問題が発生します。日付表示に時間を追加していますが、おそらくそれだけで十分です。

解決策:セレダの提案

このメソッドを追加しました:

- (NSDate *)setNoon: (NSDate *)date
{
   NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
   NSDateComponents *components = [calendar components:NSYearCalendarUnit|NSMonthCalendarUnit|NSDayCalendarUnit fromDate:date];
   [components setHour:12];
   NSDate *todayNoon = [calendar dateFromComponents:components];
   return todayNoon;
}

次に、ジャンプが行われたすべての場所で、新しいメソッドに単純にカプセル化されました。

newDate = [self setNoon:[previousCode]];
4

1 に答える 1

0

Hot Licks の回答に対するコメントに基づいてd、1975 年の春分点 (1975-03-21 05:57:00 UTC) からの日数を表す数字があり、対応する日を把握したいようです。グレゴリオ暦。

NSDateNSCalendar、およびNSDateComponentsクラスを使用して、この計算を実行できます。DST の影響を回避するには、カレンダーとフォーマッターのタイム ゾーンを UTC に設定する必要があります。

NSInteger d = 73 * 189; // days since the 1975 vernal equinox

NSTimeZone *utcTimeZone = [NSTimeZone timeZoneWithName:@"UTC"];

NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
calendar.timeZone = utcTimeZone;
NSDateFormatter *formatter = [[NSDateFormatter alloc] init]; 
formatter.dateFormat = @"yyyy-MM-dd";
formatter.timeZone = utcTimeZone;

NSDateComponents *epochComponents = [[NSDateComponents alloc] init];
epochComponents.year = 1975;
epochComponents.month = 3;
epochComponents.day = 21;
epochComponents.hour = 5;
epochComponents.minute = 57;
epochComponents.timeZone = utcTimeZone;
NSDate *epochDate = [calendar dateFromComponents:epochComponents];
NSLog(@"epochDate=%@", epochDate);
NSLog(@"epochDate from formatter=%@", [formatter stringFromDate:epochDate]);

NSDateComponents *offsetComponents = [[NSDateComponents alloc] init];
offsetComponents.day = d;

NSDate *computedDate = [calendar dateByAddingComponents:offsetComponents toDate:epochDate options:0];
NSLog(@"computedDate=%@", computedDate);
NSLog(@"computedDate from formatter=%@", [formatter stringFromDate:computedDate]);

カレンダーやフォーマッタでタイム ゾーンを UTC に設定する行をコメント アウトして、DST によって結果がどのように変化するかを確認してください。

詳細については、日付と時刻のプログラミング ガイドを参照してください。

于 2013-02-22T20:17:30.457 に答える