2012-08-29 60 views
4

我搜索我的問題字符串日期的前一天,但我沒有找到相關的任何幫助......通過字符串格式轉換的日期NSDate的結果

故事: 用戶創建一個名字繼續活動,開始日期,結束日期和註釋,因此將所有字段保存在Sqlite數據庫中。兩種日期格式都是「yyyy-MM-dd」。 之後,當用戶想要做對事件的動作,應用程序會檢查用戶的開始和結束日期,如果輸入的日期爲起始日期之前或之後結束日期通知用戶選擇的日期。

問題: I,作爲用戶,創建的活動從18-8-2012至18-9-2012。然後我在18-8-2012登錄,我被通知了。我調試了應用程序。我很驚訝。格式爲「yyyy-MM-dd」的字符串中的日期對象是「2012-08-17 19:30:00 +0000」。 的代碼是:

  #define kPickerDate @"yyyy-MM-dd" 
      NSDateFormatter *formatter = [[NSDateFormatter alloc] init]; 
      [formatter setDateFormat:kPickerDate]; 
      NSDate *sDate = [formatter dateFromString:start_date]; 
      NSDate *eDate = [formatter dateFromString:exam_date]; 

如何應用程序,??????????????

+1

它給你在不同的時區的日期(其實我的那種憐憫的人誰住在UTC他們不是被迫動搖這些蟲子他們的應用程序!)。 –

+0

包括一些代碼總是很好 – Augie

+0

我在+03:30 GMT時區,如果你的想法是真的,我應該給格林威治標準時間08:30:00 –

回答

1

您可以使用更好的方法,一個NSDate對象。首先修改NSDate的@interface(你可以在任何地方執行此操作)。要做到這一點,把它放在你的頭文件中。

@interface NSDate (missingFunctions) 
+ (NSDate *)dateWithYear:(NSInteger)year month:(NSInteger)month day:(NSInteger)day; 
@end 

然後在主文件放:

@implementation NSDate (missingFunctions) 
+ (NSDate *)dateWithYear:(NSInteger)year month:(NSInteger)month day:(NSInteger)day { 
    NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar]; 
    NSDateComponents *components = [[NSDateComponents alloc] init]; 
    [components setYear:year]; 
    [components setMonth:month]; 
    [components setDay:day]; 

    //BUT MOST IMPORTANTLY: 
    [components setTimeZone:[NSTimeZone localTimeZone]]; 
    [components setHour:hour]; 
    [components setMinute:minute]; 
    [components setSecond:second]; 

    return [calendar dateFromComponents:components]; 
} 
@end 

然後從代碼中調用(例如)在任何地方:

[NSDate dateWithYear:1969 month:8 day:15]; 

,並將在返回一個NSDate按您的要求正確的時區。您可以通過在官方的蘋果文檔中閱讀關於NSTimeZone的更多信息來更改使用哪個時區。

注意我不能讚揚寫這段代碼,但我可以保證它的工作。

+0

抱歉,但這不是安全的。我試過這個。它只有在夏令時將您的時鐘調整回到一個小時後才能運行。那時,你的NSDates將指向不同的一天。 –

+0

@StevenFisher你會提供一個解決方案(遵循這種方法),而不是工作嗎?如果重要的是當天的月份和年份以及小時和分鐘與NSDate對象無關,那麼是否可以將小時設置爲正午並且沒有任何問題?也許手動將時區設置爲UTC對於許多問題來說是更好的解決方案,但對於這個特定的問題似乎沒有必要。 – achi

+0

解決了DST情況,但它不能解決旅行問題。我有一個應用程序,就像您可能獲得的區域設置一樣(這是一所學校的信息),我仍然需要切換到UTC。 –

10

一個NSDate不只是一個日期,但也是一個時間。

你需要在每一個階段進行檢查:

  • 解析當你的日期被正確地構建?它應該是UTC的午夜,而不是本地的午夜。你可能爲此使用NSDateFormatter。確保它的時區設置爲UTC。
  • 被存儲在SQLite的日期是否正確?再次確保您將其存儲爲UTC。如果你正確解析它,但是,這應該工作。
  • 你正在格式化輸出嗎?可能使用NSDateFormatter。確保它的時區設置爲UTC。

只有一旦所有三塊都是完美的,你會在這裏沒有潛在的錯誤。

要設定一個日期格式的時區,使用方法:

formatter.timeZone = [NSTimeZone timeZoneWithAbbreviation: @"UTC"]; 

不要試圖採用本地時間來解決這個問題。

與本地時間問題:

  • 在多個時區的時間變化的一年幾次與夏令時。這一小時的差異將會把日期的一部分放到前一天!
  • 如果用戶在沒有夏令時的時區內,他們可能會前往不同的時區。同樣,你的時間的日期部分可能會被拋棄一天。

唯一安全的事情就是使用UTC。

;