1600からNSDATEから日付?
-
10-10-2019 - |
質問
私は、1600年1月1日以来、対処する必要がある日付として保存されている日付があります。これは、アプリケーションで何度も読む必要があるレガシー日付形式です。
以前は、カレンダー、空の日付コンポーネント、およびこのようなルート日付を作成していました。
self.gregorian = [[[NSCalendar alloc] initWithCalendarIdentifier: NSGregorianCalendar
] autorelease];
id rootComponents = [[[NSDateComponents alloc] init] autorelease];
[rootComponents setYear: 1600];
[rootComponents setMonth: 1];
[rootComponents setDay: 1];
self.rootDate = [gregorian dateFromComponents: rootComponents];
self.offset = [[[NSDateComponents alloc] init] autorelease];
次に、整数を後で日付に変換するには、これを使用します。
[offset setDay: theLegacyDate];
id eventDate = [gregorian dateByAddingComponents: offset
toDate: rootDate
options: 0];
(他の場所でオフセットで値を変更することはありません。)
問題は、私が別の時間を取得していることです rootDate
iOS vs. Mac OS Xでは、Mac OS Xで、私は真夜中になっています。 iOSでは、8:12:28を取得しています。 (これまでのところ、これについては一貫しているようです。)日数を追加すると、奇妙な時間が残ります。
OS | legacyDate | rootDate | eventDate ======== | ========== | ==========================|========================== Mac OS X | 143671 | 1600-01-01 00:00:00 -0800 | 1993-05-11 00:00:00 -0700 iOS | 143671 | 1600-01-01 08:12:28 +0000 | 1993-05-11 07:12:28 +0000
私の製品の以前のリリースでは、私は時間を気にしませんでした。今私がやります。なぜiOSの奇妙な時間、そしてそれについて何をすべきか? (私は時間の違いがDSTであると仮定しています。)
rootcomponentsの時間、分、秒を0に設定しようとしました。これには影響がありません。 0以外のものに設定すると、8:12:28に追加します。私は、これが跳躍秒または他の累積時計の変更と関係があるかどうか疑問に思っていました。
それとも、これは完全にiOSで使用するための間違ったアプローチですか?
解決 2
正しい答えは、物事をよりシンプルにすることだと思われます。ルートデートを作成する代わりに、毎回コンポーネントから日付を作成します。これは遅くはないはずであり、コードをアイデアに本当に近づけています。
初期セットアップ:
self.gregorian = [[[NSCalendar alloc] initWithCalendarIdentifier: NSGregorianCalendar
] autorelease];
self.components = [[[NSDateComponents alloc] init] autorelease];
[components setYear: 1600];
[components setMonth: 1];
(明らかに、プロパティとアイバーが調整されます。)
後で、実際にレガシーの日付をに変換する NSDate
:
[components setDay: 1 + theLegacyDate];
id eventDate = [gregorian dateFromComponents: components];
これにはこれらの利点があります。
- ITユーザーはivarsが少なくなります。
- コードが少ないです。
- DSTが有効かどうかにかかわらず、その日は常に真夜中に戻ります。
他のヒント
あなたは、時間の問題のために跳躍の秒/累積時計の変更について正しいと思います。あなたが実際に過去に扱っている日付はありますか、それとも純粋にarbitrary意的な時代ですか?
どちらの場合でも、今日にずっと近い新しい時代を定義することを試みることができます(たとえば、ココア時代など)。新しいエポックと古いエポックの間に1日のデルタを計算し、定数として保存します。日付を処理する必要がある場合は、このデルタを日付に適用してから、既存のnscalendarテクニックを使用しますが、古いものではなく新しいエポックを使用します。それはあなたが見ている時計のドリフトの問題を避けることを願っています。
iOSは、さまざまなタイムゾーンの非常にあいまいなルールを考慮していることに注意してください。 1月1日の真夜中です。タイムゾーンの1600は実際には7:12:28 UTCでした。日付変換のバグについて人々が不満を言う多くのケースがあり、それから誰かが実際に彼らが何年も前にいくつかの奇妙なカレンダーを変えたタイムゾーンにいることを理解しました。
データが表す正確なNSDATEを最初に確認する必要があります。 「1600年1月1日以来の日数」はナンセンスです。タイムゾーンが必要だからです!あなたがすべきこと:それが何日を表すべきかを知っている「遺産」番号を見つけてください。たとえば、143671が1993年5月11日にタイムゾーンであることを「知っている」場合は、その日付からルートの日付として開始し、(x -143671)日を追加します。