2014-07-23 46 views
0

我真的非常難以理解真正簡單的東西。我的應用程序的一個功能是每月重複事件,所以我需要一個日期,添加一個月,並存儲它。我每個月都會重複一遍。CoreData&NSDate - 日期存儲在2015年落後1天

我遇到的問題是我在測試時發現,當日期到2015年3月失去一天 - 所以3月22日變成3月21日... 4月... 5月等等。甚至陌生人事情一旦我從2016年3月份開始,它就會轉回到第22位 - 不再錯過一天。

據我所知,它不能是夏令時,因爲它發生在12個月的時期,或閏年,因爲2015年不是閏年。

我正在使用MagicalRecord來幫助CoreData,我敢肯定它可能與CoreData本身有關?這裏的所謂的更新日期的簡單代碼:

// create date if we haven't already 
    if (!_dateEntity.theDate) { 
     NSDate *date = [NSDate date]; 
     _dateEntity.theDate = date; 
    } 

    NSLog(@"date before update - %@", _dateEntity.theDate); 

    // add a month to it 
    NSCalendar *calendar = [NSCalendar currentCalendar]; 
    NSDateComponents *components = [[NSDateComponents alloc] init]; 
    [components setMonth:1]; 
    _dateEntity.theDate = [calendar dateByAddingComponents:components toDate:_dateEntity.theDate options:0]; 

    NSLog(@"date after update - %@ \n ***** \n", _dateEntity.theDate); 

    // save the context 
    [[NSManagedObjectContext MR_defaultContext] MR_saveToPersistentStoreWithCompletion:^(BOOL success, NSError *error) { 
     if (success) { 
      //NSLog(@"You successfully saved your context."); 
     } else if (error) { 
      //NSLog(@"Error saving context: %@", error.description); 
     } 
    }]; 

這是半須藤代碼,從實際項目中剝離出來成爲一個獨立的項目只是爲了測試(!以確保我不會瘋)

這裏(的要求)是原木的Xcode:

2014-07-23 10:48:55.001 dateTest[52136:60b] date before update - 2014-07-23 09:48:54 +0000 
2014-07-23 10:48:55.003 dateTest[52136:60b] date after update - 2014-08-23 09:48:54 +0000 
***** 
2014-07-23 10:48:59.994 dateTest[52136:60b] date before update - 2014-08-23 09:48:54 +0000 
2014-07-23 10:48:59.995 dateTest[52136:60b] date after update - 2014-09-23 09:48:54 +0000 
***** 
2014-07-23 10:49:04.685 dateTest[52136:60b] date before update - 2014-09-23 09:48:54 +0000 
2014-07-23 10:49:04.686 dateTest[52136:60b] date after update - 2014-10-23 09:48:54 +0000 
***** 
2014-07-23 10:49:08.127 dateTest[52136:60b] date before update - 2014-10-23 09:48:54 +0000 
2014-07-23 10:49:08.128 dateTest[52136:60b] date after update - 2014-11-23 10:48:54 +0000 
***** 
2014-07-23 10:49:12.594 dateTest[52136:60b] date before update - 2014-11-23 10:48:54 +0000 
2014-07-23 10:49:12.595 dateTest[52136:60b] date after update - 2014-12-23 10:48:54 +0000 
***** 
2014-07-23 10:49:16.014 dateTest[52136:60b] date before update - 2014-12-23 10:48:54 +0000 
2014-07-23 10:49:16.015 dateTest[52136:60b] date after update - 2015-01-23 10:48:54 +0000 
***** 
2014-07-23 10:49:20.188 dateTest[52136:60b] date before update - 2015-01-23 10:48:54 +0000 
2014-07-23 10:49:20.189 dateTest[52136:60b] date after update - 2015-02-23 10:48:54 +0000 
***** 
2014-07-23 10:49:32.956 dateTest[52136:60b] date before update - 2015-02-23 10:48:54 +0000 
2014-07-23 10:49:32.957 dateTest[52136:60b] date after update - 2015-03-23 10:48:54 +0000 
***** 
2014-07-23 10:49:44.061 dateTest[52136:60b] date before update - 2015-03-23 10:48:54 +0000 
2014-07-23 10:49:44.061 dateTest[52136:60b] date after update - 2015-04-23 09:48:54 +0000 
***** 

從日誌中,一切都看起來不錯 - 還是在23日(今天)。但是,如果我實際查看數據庫本身,則最後兩個日期2015-03-23和2015-04-23分別顯示爲2015-03-22和2015-04-22。

在數據庫中的最新更新,如圖中的SQL瀏覽器: 2015年4月22日10時48分54秒

他們將這樣的表現,直到2016年3月,在這一點上,他們會去回到正確存儲。這是我真的不明白的一點。

任何人都曾經歷過類似的事情?我現在正在撕掉我的頭髮

+0

可否請您在添加月份前後登錄您的'_dateEntity.theDate',然後將結果作爲更新添加到帖子中? – Lebyrt

+0

當然,只是爲你做。謝謝你的幫助! –

+0

請問您可以發佈2015-03-23和2015-04-23最後兩個日期,因爲它們出現在數據庫中,但也包含時間和時區? – Lebyrt

回答

0

我相信這確實是夏令時問題,而不是核心數據問題。當間隔跨越標準時間到DST或從標準時間到DST時,您的時間間隔計算會給您帶來意想不到的結果。

試試這個例子中,無核心數據:

NSDate *dateNow = [NSDate date]; 

    // add a month to it 
    NSCalendar *calendar = [NSCalendar currentCalendar]; 
    NSDateComponents *components = [[NSDateComponents alloc] init]; 
    [components setMonth:1]; 
    components.calendar = calendar; 
    NSDate *dateNowPlusOneMonth = [calendar dateByAddingComponents:components toDate:dateNow options:0]; 

    NSLog(@"now %@", dateNow); 
    NSLog(@"now plus one month %@", dateNowPlusOneMonth); 

    NSDate *dateMarch01 = [NSDate dateWithTimeIntervalSince1970:1425206934]; 
    // add a month to it 
    NSDate *dateMarch01PlusOneMonth = [calendar dateByAddingComponents:components toDate:dateMarch01 options:1]; 
    NSLog(@"Interval straddles ST/DST changeover date in USA"); 
    NSLog(@"March 01 %@", dateMarch01); 
    NSLog(@"March 01 plus one month %@", dateMarch01PlusOneMonth); 

    NSDate *dateMarch23 = [NSDate dateWithTimeIntervalSince1970:1427107734]; 
    // add a month to it 
    NSDate *march23PlusOneMonth = [calendar dateByAddingComponents:components toDate:dateMarch23 options:0]; 
    NSLog(@"Interval is after ST/DST changeover date in USA"); 
    NSLog(@"March 23 %@", dateMarch23); 
    NSLog(@"March 23 plus one month %@", march23PlusOneMonth); 

下面是輸出(與NSLog的時間戳刪除):

now 2014-07-23 18:03:22 +0000 
now plus one month 2014-08-23 18:03:22 +0000 

Interval straddles ST/DST changeover date in USA 
March 01 2015-03-01 10:48:54 +0000 
March 01 plus one month 2015-04-01 09:48:54 +0000 

Interval is after ST/DST changeover date in USA 
March 23 2015-03-23 10:48:54 +0000 
March 23 plus one month 2015-04-23 10:48:54 +0000 

要添加到這個問題的卑鄙的性質,你會在程序中看到不同的結果,具體取決於用戶的時區(真正的DST更改日期)。澳大利亞,英國和美國都會有輕微不同的錯誤行爲!

日期和時間編程指南的清單10說明了「在本週獲取星期日」。我認爲你需要適應這個過程,比如「在下個月獲取當前日期和時間」。

相關問題