2009-08-05 27 views
8

我一直在試圖找到一種在iPhone上使用Core Data存儲日常數據的明智方式。如何在沒有時間的核心數據中存儲日期

我的應用程序接收數據以CSV格式,帶有日期,但沒有時間:

date, cycles 
2009-08-01, 123 
2009-08-02, 234 
2009-08-03, 345 
2009-08-04, 456 

當此數據存儲,應該每天只有一條記錄。我想最好的辦法是創建一個NSDate進行存儲,但是會刪除時區數據&。

我可以使用NSDateComponents或NSDateFormatter輕鬆創建NSDate,無需小時,分鐘或秒。但是,即使當我設置時區明確爲UTC或從GMT零秒,輸出用的NSLog創建日期()總是有我的本地時區,如:

2009-07-29 00:00:00 +0100 

有誰知道一個更好的方式來使NSDates沒有時間組件?或者更好的方式來存儲日期?

回答

9

一個好的編程經驗法則是始終以UTC來存儲日期。無論您是否使用核心數據都無關緊要;你仍然需要做一些工作,因爲蘋果的日期類很吸引人。

日期在內部表示爲從參考日期開始的秒數,我相信,2001年1月1日00:00:00(儘管實際的參考日期不是很重要)。點是,NSDate對象始終以UTC爲本地。如果你在CSV文件中獲得的日期是本地的,你需要做這樣的事情來獲得UTC時間:

NSDate *UTCDate = [localDate addTimeInterval:-[[NSTimeZone localTimeZone] secondsFromGMT]]; 

然後,我的時間設定爲00:00:00 。現在,您將在午夜以UTC保存日期。出於演示目的,您將使用配置了您所選時區的NSDateFormatter(系統時區是默認值(如果未指定),以顯示這些日期。

雖然時間只是在處理日期,但時區並不重要。只要您確保將NSDateFormatter上的時區設置爲UTC,無論用戶在其設備上選擇了哪個時區,都會顯示相同的日期。

如果您不喜歡此解決方案,您可以隨時以其他格式存儲日期。您可以使用doubleint以某種自定義格式(例如自某個參考日期以來的天數),或者您甚至可以滾動自己的班級以按照您想要的方式對日期進行建模,並將其作爲NSData對象存儲。只要該類實現NSCoding,就可以將其序列化爲核心數據中的NSData對象。您只需要將Core Data中的屬性類型設置爲「Transformable」即可。

這裏有很多選項,它們都不涉及編寫自己的SQLite查詢和數據庫的工作。

+1

非常感謝。我已經把它整理好了。您的答案使轉換更有意義,Peter Hosey的下文解釋了NSLog輸出。 – Ben 2009-08-05 17:22:21

2

NSDate對象將始終包含時間日期 - 引用它「代表單個時間點」的文檔,並通過存儲自參考日期以來的時間值(2001年1月1日開始於格林威治標準時間,再次根據文檔)。因此你不能有一天不知道時間的NSDate。

與其按照自己的方式嘗試和存儲日期,我仍然會在模型中使用NSDate,並考慮向您的實體類添加一對方法,其中一個方法將執行您上面所述的操作,將NSDate設置爲00:某一天的00:00。另一個可能會以您的首選格式返回NSDate的日期。這些會使用核心數據生成的getter和setter來訪問NSDate屬性。

通過仍然使用NSDate,您正在使用Core Data可以與本機一起工作的類,這意味着您仍然可以輕鬆地使用謂詞進行過濾,或按照日期對取回的結果進行排序,而不必過多考慮它。

+0

感謝您的回覆。這仍然會導致時區問題。例如:我將數據保存在七月份的倫敦(GMT + 0100),其他人將它保存在Cupertino(GMT-0700)中。存儲日期現在有8小時不同。我認爲只要退回原始SQLite可能會更有效。 – Ben 2009-08-05 13:31:07

+0

我不太明白這個問題:NSDate中的日期存儲爲絕對日期,自00:00:00 1/1/2001 * GMT *以來的秒數。因此,如果兩個不同時區的人在同一時刻存儲「當前」日期,則他們的NSDate是相同的。 時區只能用於檢索/顯示,除非您告訴NSDate,否則它將與系統區域設置時區一起使用。 換句話說,如果你的兩組數據在倫敦和庫比蒂諾同時存儲,那麼存儲日期是相同的,沒有區別。 – marramgrass 2009-08-05 14:56:13

3

NSDate沒有時區。 NSLog使用您當地的時區;它說+0100,因爲那是你的位置。

相關問題