2010-06-22 25 views
26

返回nil我有下面的代碼在OS 3.x的工作NSDateFormatter在OS 4.0

NSString *stringDate = @"2010-06-21T20:06:36+00:00"; 
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; 
[dateFormatter setDateFormat:@"yyyy-MM-dd'T'HH:mm:ssZ"]; 
NSDate *theDate = [dateFormatter dateFromString:stringDate]; 
NSLog(@"%@",[dateFormatter stringFromDate:theDate]); 

,但現在在iOS4的模擬器下最新的Xcode 3.2.3,該varialble theDate爲零。

我已經查看了類的引用,並沒有看到任何不贊成使用這些特定方法的iOS4或實現不同的方法。我放棄了什麼?

+0

看來如果我從stringDate去掉「+00:00」然後帶走「Z」格式,它會正常工作,但這不是一個真正的選擇,因爲我得到的動態數據有附加的時區,我真的不想在每次獲得的日期都撕掉那部分。我找不到任何文檔說這種方式不再支持時區。 – AtomRiot 2010-06-22 16:57:57

+4

我想我想通了。我給出的格式是RFC 822和GMT之間的一半。如果我將「+00:00」更改爲「+0000」,那麼我可以在我的格式上使用「Z」。如果我將其更改爲「GMT + 00:00」,則可以使用ZZZZ正確獲取數據。看來有些東西已經被剝離出來處理這個混合,因爲它之前使用OS 3.x爲我工作。 – AtomRiot 2010-06-22 17:32:11

回答

41

我發現,如果你做這種方式它的工作原理(見下文) 。關鍵是使用方法: - [NSDateFormatter getObjectValue:forString:range:error:]

,而不是

-[NSDateFormatter dateFromString]

的完整代碼:

+ (NSDate *)parseRFC3339Date:(NSString *)dateString 
{ 
    NSDateFormatter *rfc3339TimestampFormatterWithTimeZone = [[NSDateFormatter alloc] init]; 
    [rfc3339TimestampFormatterWithTimeZone setLocale:[[[NSLocale alloc] initWithLocaleIdentifier:@"en_US_POSIX"] autorelease]]; 
    [rfc3339TimestampFormatterWithTimeZone setDateFormat:@"yyyy-MM-dd'T'HH:mm:ssZ"]; 

    NSDate *theDate = nil; 
    NSError *error = nil; 
    if (![rfc3339TimestampFormatterWithTimeZone getObjectValue:&theDate forString:dateString range:nil error:&error]) { 
     NSLog(@"Date '%@' could not be parsed: %@", dateString, error); 
    } 

    [rfc3339TimestampFormatterWithTimeZone release]; 
    return theDate; 
} 
+0

謝謝。 dateFromString:和getObjectValue:forSting:range:error:行爲確實不同。後者的確可以正常工作,而前者在相同的字符串(包括冒號)上扼流。 – 2010-11-15 10:46:12

+0

非常感謝...... :) – 2011-10-25 12:01:00

+0

優秀的代碼,謝謝。 – 2013-06-14 13:30:55

0

看起來不錯。

它在真實設備上仍能正常工作嗎?

如果有文件爲模擬器的bug報告,否則文件爲iOS 4

+0

我無法在設備上測試,現在我的設備已經搞亂了。我希望這只是一個模擬器問題,但dateformatter似乎並不是模擬器會遇到的問題。 – AtomRiot 2010-06-22 16:03:01

+0

好的,只是在設備上試過這段代碼,我看到了與模擬器相同的行爲。 :( – AtomRiot 2010-06-22 16:10:13

8

bug報告是您的設備設置爲24小時模式或12小時制?

這聽起來像一個瘋狂的問題,但我剛剛遇到該錯誤 - dateformatter將根據當前的語言環境調整您的格式字符串,其中將包括時間格式設置。

您可以強制它通過加入這一行忽略它們:

dateFormatter.locale = [[NSLocale alloc] initWithLocaleIdentifier:@"en_US_POSIX"]; 

希望有所幫助。

+1

嗯,我沒有看到它有任何區別,仍然從dateFromString調用得到空值。 – AtomRiot 2010-06-22 16:22:53

+0

在這種情況下,我的答案是完全錯誤的。對不起! – deanWombourne 2010-06-23 10:33:53

+0

這是一個2.x天的錯誤。是否它仍然存在,因爲我最終解析字符串「手動」。 – 2010-06-25 15:34:02

2

我最近遇到這個問題。我最終使用了Peter Hosey的ISO8601解析器。它在這裏可用:http://boredzo.org/iso8601unparser/

+0

這救了我的命,謝謝。我更喜歡使用特定的解析器而不是修改輸入日期字符串。 – scalbatty 2010-07-13 07:55:10

1

我從dataFormat得到的值@"yyyy'-'MM'-'dd'T'HH':'mm':'ss'+'hh:mm";

+0

到時區爲止的一切都沒有給我帶來麻煩。這只是時區的一部分。我得到的是時區數據,所以我不得不在解析之前改變輸入 – AtomRiot 2010-06-27 15:48:11

0

我只是在調試這個完全相同的問題。我有和你在3.x中一樣的日期字符串,而不是4.0。同樣的症狀。

當翻翻NSDateFormatter文檔,我看到:

初始化日期格式化 - 通過iPhone OS 3.2

這就是說init方法已經被廢棄了的iOS 4.0的iPhone OS 2.0初始化可用。我不確定那是什麼意思。

+0

我還看到,當通讀類參考時,它沒有提及它的含義。而且Xcode不會將其標記爲depricated。 – AtomRiot 2010-06-27 15:49:16

0

Elfred發佈的鏈接做了訣竅。我偶然發現了同樣的問題,同時將我的應用程序從3.1.3轉換爲iOS4。該鏈接持有ISO8601DateFormatter類,這是一個非常優秀的擴展,然後是我自己的日期實用程序類。

Elfred wrote: I ran into this issue recently. I ended up using Peter Hosey's ISO8601 parser. It is available here: http://boredzo.org/iso8601unparser/

1

我給出的格式是RFC 822和GMT之間的一半。如果我將「+00:00」更改爲「+0000」,那麼我可以在我的格式上使用「Z」。如果我將其更改爲「GMT + 00:00」,則可以使用ZZZZ正確獲取數據。看來有些東西已經被剝離出來處理這個混合,因爲它之前使用OS 3.x爲我工作。

0

看來NSDateFormatter變得非常挑剔。

-(void)dateFormatterTests { 
    NSDateFormatter *formatter; 

    formatter = [[NSDateFormatter alloc] init]; 

#ifdef WORKS 
    [formatter setDateFormat:@"yyyy-MM-dd"]; 
#elif defined(ALSO_WORKS) 
    [formatter setDateFormat:@"yyyy MM dd"]; 
    [formatter setLenient:YES]; 
#else // DOESN'T WORK 
    [formatter setDateFormat:@"yyyy MM dd"]; 
#endif 

    // Works per comments above 
    NSLog(@"dFS: %@", [formatter dateFromString:@"2010-01-13"]); 
    // Never works with any of the above formats 
    NSLog(@"dFS: %@", [formatter dateFromString:@"2010-01-13 22:00"]); 

    [formatter release]; formatter = nil; 
} 
+0

此代碼不考慮時區。我正在以特定格式給予時區,我無法改變這種情況。 – AtomRiot 2010-07-22 02:51:06

+0

對不起。這篇文章的要點是,如果你認爲它應該產生一些東西,例如只解碼日期時,格式化程序將返回零,但也會在字符串中添加一個時間。我很高興你能工作。 – 2010-07-22 17:39:16

0

我在我的應用程序以及Null Value from NSDateFormatter中遇到了同樣的問題。

,我發現我的問題是以下幾點:

我送我的應用程序的日期和時間如下:07/16/2010 04:21:00 +00:00與格式如下:[dateFormatter setDateFormat:@"MM/dd/yyyy HH:mm:ss ZZZ"]

這似乎是格式化的ZZZ部分不再接受冒號:在當時。

作品:07/16/2010 04:21:00 +0000

不起作用:07/16/2010 04:21:00 +00:00

支持當前的應用程序,都出來了,我所做的只是搜索字符串中的+00:00一部分,並與+0000更換。

希望這可以幫助別人。

5

此代碼將刪除多餘的冒號作爲AtomRiot描述:

Converting it from:

  • NSString *stringDate = @"2010-06-21T20:06:36+00:00";

to:

  • NSString *stringDate = @"2010-06-21T20:06:36+0000";
// Remove colon in timezone as iOS 4+ NSDateFormatter breaks 
if (stringDate.length > 20) { 
    stringDate = [stringDate stringByReplacingOccurrencesOfString:@":" 
                 withString:@"" 
                  options:0 
                  range:NSMakeRange(20, stringDate.length-20)]; 
} 

詳細內容見:https://devforums.apple.com/thread/45837

+0

非常感謝... – 2010-08-31 12:41:12

0

我使用它那樣簡單:

date_formatter = [[NSDateFormatter alloc] init]; 
     [date_formatter setDateStyle:NSDateFormatterShortStyle]; 
     [date_formatter setTimeStyle:NSDateFormatterNoStyle]; 

,這很好。我不明白他們怎麼能不建議使用init方法,當NSDateFormatter類是從NSObject的子類

2

這似乎是蘋果的文檔,很好,「棘手」:

The format string uses the format patterns from the Unicode standard (this reference is to version tr35-6 for Mac OS X v10.5; for Mac OS X v10.4 use version tr35-4).

iOS: The v10.0 compatibility mode is not available on iOS—only the 10.4 mode is available.

根據版本tr35-4

Use 1 for GMT format, 2 for RFC 822

Z{1} GMT-08:00
Z{2} -0800

但根據的Unicode標準:

Use one to three letters for RFC 822, four letters for GMT format.

Z{1,3} -0800
Z{4} GMT-08:00

所以它看起來像iOS 4的使用tr35-6 - Unicode標準,這也是爲什麼+00:00現在無法對 'Z' 。在我NSDateFormatter 00反對 'ZZZZ',它中的iOS 4 GMT-08失敗

我試圖-08 00,但是,沒有工作。現在看來,時區(GMT)現在是必需的,而不是可選的,因爲它可能已經在iOS 3中。