2013-04-01 69 views
0

我有一個函數,根據用戶的位置生成當前日期。即使在英國的夏令時發生變化之後,這也能提供正確的日期和時間。NSDateformatter夏時制後不正確的時間

但是當我嘗試創建它似乎對我多加一個小時的日期字符串...

存儲在Coredata

例如,日期是2013年1月3日卻在12:00轉化爲字符串顯示爲1/3/2013 13:00。隨着語言環境和時區的變化,似乎沒有什麼區別。

任何想法如何解決這個問題?值得注意的是,我從來沒有用正確的時區創建日期時間的「本地日期」功能。

代碼:

+(NSDate*)localDate{ 

NSDate* date = [NSDate date]; 

NSTimeZone* sourceTimeZone = [NSTimeZone timeZoneWithAbbreviation:@"GMT"]; 
NSTimeZone* destinationTimeZone = [NSTimeZone localTimeZone]; 

NSInteger sourceGMTOffset = [sourceTimeZone secondsFromGMTForDate:date]; 
NSInteger destinationGMTOffset = [destinationTimeZone secondsFromGMTForDate:date]; 
NSTimeInterval interval = destinationGMTOffset - sourceGMTOffset; 
return [NSDate dateWithTimeInterval:interval sinceDate:date]; 

}

格式化代碼:

-(NSString*)dateWithTime{ 
NSDateFormatter*formatter = [[NSDateFormatter alloc]init]; 

[formatter setDateFormat:@"dd"]; 
NSInteger day = [[formatter stringFromDate:self]integerValue]; 
NSInteger fullday = day; 
NSString* strDay = @""; 
if(day>29){ 
    day = day - 30; 
} 
else if(day>19){ 
    day = day - 20; 
} 

else if(day>9){ 
    day = day - 10; 
} 

if(fullday ==11){ 
    strDay = @"th"; 
} 
else if(fullday ==12){ 
    strDay = @"th"; 
} 
else if(fullday ==13){ 
    strDay = @"th"; 
} 
else if(day == 1){ 
    strDay = @"st"; 
} 
else if(day ==2){ 
    strDay = @"nd"; 
} 
else if(day ==3){ 
    strDay = @"rd"; 
} 
else{ 
    strDay = @"th"; 
} 

[formatter setDateFormat:@"MMMM"]; 
NSString* month = [formatter stringFromDate:self]; 

[formatter setDateFormat:@"HH:mm"]; 
NSString* time = [formatter stringFromDate:self]; 

return [NSString stringWithFormat:@"%u%@ %@ %@ - %@",fullday,strDay,month,[self yearString],time]; 

} 

編輯:即使NSDateComponants返回不正確的時間..

NSCalendar *gregorian = [NSCalendar currentCalendar]; 
NSDateComponents *dateComponents = [gregorian components:(NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit) fromDate:self]; 
+0

甚至一年較小? –

+0

DateFormatter不能通過@「dd」找到,因爲你有'NSDateComponent'' [comp date]'會給你當前的日期。 –

+0

剛剛更新。組件給我同樣的問題。它就像格式化程序正在增加一小時......(它只是在時鐘改變後纔出現) – Dan

回答

2

的NSDate不知道關於時間只有在轉換時區時纔算,所以你的localDate方法可能會以你不想要的方式欺騙​​事物。你可能需要做的是設置格式或日曆到本地區域的時區,所以:

[formatter setTimeZone:localTimeZone]; 

[gregorian setTimeZone:localTimeZone]; 

,並留下單獨[NSDate date]返回的值。

+0

這似乎沒有什麼區別。我不知道這個問題是由我的當地日期造成的... – Dan

+0

是的,我預計格式化程序和日曆的時區實際上是localTimeZone默認情況下。 –

0

設置dateformatter的語言環境;

NSLocale *enUSPOSIXLocale = [[NSLocale alloc] initWithLocaleIdentifier:@"en_US_POSIX"]; 
[dateFormatter setLocale:enUSPOSIXLocale]; 
0

根據您設置初始日期/時間後的需要,您可能希望在時區(包括DST)發生變化時收到通知。如果是這樣,applicationSignificantTimeChange:將是你的朋友。

3

請注意,在控制檯中打印NSDate將始終以UTC打印日期。

只需在您的數據庫中存儲[NSDate date]。當用戶從不改變它的時區時,從數據庫讀取日期並格式化它將返回正確的結果。

核心數據中的NSDate對象存儲爲具有UTC時區的UNIX時間戳。在讀取和格式化日期對象時,會應用用戶的當前時區。

當使用核心數據存儲日期並且對不同時區具有依賴性時,正確設置日期格式的唯一方法是將適當的時區(字符串時區名稱)也存儲起來。閱讀和格式化日期對象時,必須將存儲的時區應用於dateFormatter。然後你會得到正確的結果。