2014-03-31 85 views
1

考慮下面的代碼串:NSDateFormatter失敗,這似乎正確

NSDateFormatter *formatter = [[NSDateFormatter alloc] init]; 
[formatter setDateFormat:@"yyyy-MM-dd'T'HH:mm:ss"]; 
NSLog(@"Date from String: %@", [formatter dateFromString:@"2013-09-08T00:36:40"]); 

日誌生成:日期從字符串:(空)

對於從它的工作原理相同來源的其他字符串,但我米沒有看到爲什麼在這種情況下失敗。

有人能教導我嗎?

更新:如下我已經更新了代碼,仍然失敗:

NSDateFormatter *formatter = [[NSDateFormatter alloc] init]; 
[formatter setDateFormat:@"yyyy-MM-dd'T'HH:mm:ss"]; 
NSLocale *locale = [NSLocale localeWithLocaleIdentifier:@"en_US_POSIX"]; 
[formatter setLocale:locale]; 

NSDate *date = nil; 
NSError *error = nil; 

[formatter getObjectValue:&date 
         forString:@"2013-09-08T00:36:40" 
          range:NULL 
          error:&error]; 

NSLog(@"Date from String: %@", date); 
NSLog(@"Error: %@", error); 

輸出: 2014-03-31 15:27:01.697無題:從字符串[30859 507]日期: (null) 2014-03-31 15:27:01.710無標題[30859:507]錯誤:錯誤域= NSCocoaErrorDomain代碼= 2048「值」2013-09-08T00:36:40「無效。的UserInfo = {0x7f89d8e04cd0 = NSInvalidValue 2013-09-08T00:36:40}

更新2:一些玩弄我發現我的時區後,它失敗(我不明白爲什麼的原因,但它只我的時區下失敗)

下面的代碼失敗:

NSDateFormatter *formatter = [[NSDateFormatter alloc] init]; 
[formatter setDateFormat:@"yyyy-MM-dd'T'HH:mm:ss"]; 
NSLocale *locale = [NSLocale localeWithLocaleIdentifier:@"en_US_POSIX"]; 
[formatter setLocale:locale]; 
[formatter setTimeZone:[NSTimeZone timeZoneWithName:@"America/Santiago"]]; 

NSDate *date = nil; 
NSError *error = nil; 

[formatter getObjectValue:&date 
         forString:@"2013-09-08T00:36:40" 
          range:NULL 
          error:&error]; 

NSLog(@"Date from String: %@", date); 
NSLog(@"Error: %@", error); 

任何建議,以解決它?

+0

我無法重現您的問題,但我通過在更新後關閉投票而收回。 –

+0

那麼,在第二種情況下記錄什麼? –

+0

我也無法重現您的問題。我想你應該考慮@MartinR鏈接。 – Pawan

回答

1

錯誤是因爲該日期不智利區域下存在(因爲DST變化)引起的。

雖然NSDateFormatter是正確的返回零,因爲它不存在。告訴用戶「該文件是在您的時區從未經歷過的時間內創建的」是不可行的。

溶液(即適用於具有DST的任何其它區)是設定一個時區就像當前一個不DST。

NSString *dateString = ...; //Assume it is defined 
NSDateFormatter *formatter = [[NSDateFormatter alloc] init]; 
[formatter setDateFormat:@"yyyy-MM-dd'T'HH:mm:ss"]; 
NSLocale *locale = [NSLocale localeWithLocaleIdentifier:@"en_US_POSIX"]; 
[formatter setLocale:locale]; 
//Date formatting might fail because of Daylight Saving Timezones and the like. So, we force the timezone to one just like it where the date always exist. 
[formatter setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:[[NSTimeZone localTimeZone] secondsFromGMT]]]; 

NSDate *date = nil; 
NSError *error = nil; 

[formatter getObjectValue:&date 
         forString:dateString 
          range:NULL 
          error:&error]; 

同樣,這在技術上並不正確,但可以做顯示。

+0

強制設置語言環境解決了它,謝謝 – Laszlo

2

根據http://www.timeanddate.com/time/zone/chile/santiago,美國/聖地亞哥時區的夏令時 從2013年9月8日星期日00:00開始,這意味着時鐘向前調整了1小時到太陽, 9月8日,01:00。

因此時間「零時36分四十秒」並不當日存在。這就是 轉換失敗的原因。

一個可能的解決辦法是,以填補在給定的成分 一個NSDateComponents然後調用dateFromComponents

NSCalendar *cal = [NSCalendar currentCalendar]; 
[cal setTimeZone:[NSTimeZone timeZoneWithName:@"America/Santiago"]]; 
NSDateComponents *comp = [[NSDateComponents alloc] init]; 
comp.year = 2013; 
comp.month = 9; 
comp.day = 8; 
comp.hour = 0; 
comp.minute = 36; 
comp.second = 40; 
NSDate *d = [cal dateFromComponents:comp]; 
NSLog(@"Date from components: %@", d);  // 2013-09-08 04:36:40 +0000 
NSString *s = [formatter stringFromDate:d]; 
NSLog(@"String from date: %@", s);   // 2013-09-08T01:36:40 

這給同日所有「有效」日期字符串,也是一個合理的結果 爲夏令時轉換期間的「無效」日期字符串。

+0

我想這可能是因爲當我發現這是因爲時區。但我仍然需要顯示日期。我會發布解決方案,找到我需要的套件。 –

+0

@DiegoTorres:我發現了一種不同的解決方法,也許你可以使用它。 –

+0

在我的情況下,它不會很容易工作,因爲我仍然需要解析提供的字符串。好的解決方法壽。 –