2011-01-12 68 views
1

我有一個日期存儲爲1600年1月1日以來我需要處理的天數。這是一種遺留日期格式,我需要在我的應用程序中多次閱讀。自1600起至NSDate的日期?

以前,我一直在創建日曆,空日期組件和根日期如下:

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與Mac OS X的Mac OS X的,我越來越midn飛行。在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?

回答

1

看起來正確的答案是讓事情變得更簡單。我不是每次都創建一個rootDate,而是從組件創建日期。這應該不會更慢,並且仍然保持代碼真的接近這個想法。

初始設置:

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]; 

這有這些我的優點:

  1. 它減少了ivars用戶。
  2. 它代碼較少。
  3. 無論DST是否生效,它總是在當天午夜返回。
3

我想你是正確的閏秒/累計時鐘變化佔時間問題。你過去處理的日期,還是純屬任意時代?

在任何一種情況下,您都可以嘗試定義一個更接近當前日子的新時代(比如可可時代)。計算新紀元和舊紀元之間的日增量並將其保存爲常數。當你需要處理一個日期時,應用這個增量到日期,然後使用你現有的NSCalendar技術,但是用你的新時代而不是舊時代。這將有望避免你所看到的時鐘漂移問題。

+0

這是一個好主意,但不幸的是它仍然會留下+/- 1小時的誤差。 – 2011-01-12 19:44:53

0

請注意,iOS會考慮各種時區的非常隱蔽的規則。這很可能是1月1日午夜。你的時區1600實際上是在UTC時間7:12:28。有很多情況下,人們抱怨日期轉換中的錯誤,然後有人發現他們實際上處於某個時區,這使得許多年前奇怪的日曆發生了變化。

您需要首先找出您的數據所代表的確切NSDate。 「1600年1月1日以來的天數」是無稽之談,因爲你需要一個時區!你應該做什麼:找到一個「遺產」號碼,你知道它應該代表哪一天。例如,如果您「知道」143671應該在您的時區爲1993年5月11日,那麼以該日期作爲根日期並向其添加(x-143671)天。