dan*_*dee 6 iso8601 nsdateformatter timezone-offset
由于iOS的7,NSDateFormatter 确实当与此格式的字符串呈现的确创造一个NSDate:
NSDateFormatter *formatter = [NSDateFormatter new];
[formatter setDateFormat:@"@"yyyy'-'MM'-'dd'T'HH':'mm':'ssZ""];
NSLog(@"non–nil date, even honoring the 7–minute–offset in the time–zone on iOS 7: %@",
[formatter dateFromString:@"2011-07-12T18:07:31+02:07"]);
Run Code Online (Sandbox Code Playgroud)
对于iOS 6,答案是不使用NSDateFormatter ......
好的,到目前为止我已经读过了
关于如何使用NSDateFormatter以创建NSDate一个字符串.
我偶然发现了Peter Hosey的ISO8601DateFormatter.
看看他的实施,我想知道:
是不是有什么办法,既正确和理智来得到这样一个字符串2011-07-12T18:07:31+02:00到NSDate?
GMT前缀"+" - 符号,那将是没有问题的,但......我可以破解它为我的应用程序工作(使用格式@"yyyy'-'MM'-'dd'T'HH':'mm':'ssz':'00"),但这当然是不正确的,因为它会丢弃时区的分钟信息.
我也可以用空字符串替换最后一个冒号,但我也认为这也是一个黑客.
那么,是否有一些秘密的酱汁NSDateFormatter从上面拿出那根绳子给我一个有效和正确的NSDate?
我找到了一个小贴士,可以+[NSDate dateWithNaturalLanguageString:]用来实现我的目标.然而 - 这只是设定日期,而不是时间!(它确实设置了时间,但只考虑了时区偏移而不是HH:mm:ss部分......)
这个问题有点老了,但我也遇到了同样的问题。我想出了一些代码,这是一个答案,可能对其他人有用......
我使用正则表达式来解析 ISO-8601 字符串并将输出抓取到一堆字符串中,然后您可以使用它来创建自己的字符串以传递到 NSDateFormatter (即删除冒号等),或者如果您总是想要相同的输出string,只需根据调用 NSRegularExpression 的结果创建它即可。
// ISO-8601 regex:
// YYYY-MM-DDThh:mm[:ss[.nnnnnnn]][{+|-}hh:mm]
// Unfortunately NSDateFormatter does not parse iso-8601 out of the box,
// so we need to use a regex and build up a date string ourselves.
static const char * REGEX_ISO8601_TIMESTAMP =
"\\A(\\d{4})-(\\d{2})-(\\d{2})T(\\d{2}):(\\d{2})" // Mandatory - YYYY-MM-DDThh:mm
"(?:"
":(\\d{2})" // Optional - :ss
"(?:"
"[.](\\d{1,6})" // Optional - .nnnnnn
")?"
")?"
"(?:"
"([+-])(\\d{2}):(\\d{2})|Z" // Optional -[+-]hh:mm or Z
")?\\z";
// Extract all the parts of the timestamp
NSError *error = NULL;
NSString *regexString = [[NSString alloc] initWithUTF8String:REGEX_ISO8601_TIMESTAMP];
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:regexString
options:NSRegularExpressionCaseInsensitive
error:&error];
NSArray *matches = [regex matchesInString:timestamp
options:0
range:NSMakeRange(0, [timestamp length])];
// Groups:
//
// elements start at 1 in the array returned from regex, as [0] contains the original string.
//
// MANDATORY - must exist as per ISO standard
// 1 - YYYY
// 2 - MM
// 3 - DD
// 4 - hh
// 5 - mm
// OPTIONAL (each one can be optional)
// 6 - ss
// 7 - nn (microseconds)
// 8 - offset sign (+/-)
// 9 - offset hour
// 10 - offset min
// put the parts into a string which will then be recognised by NSDateFormatter
// (which is acutally RFC822 format)
// mandatory init'd to nil, optional set to defaults.
NSString *YYYY, *MM, *DD, *hh, *mm, *ss, *nn, *sign, *Zhh, *Zmm;
NSRange tempRange;
for (NSTextCheckingResult *match in matches) {
NSRange matchRange = [match range];
NSInteger matchCount = [match numberOfRanges] - 1;
NSUInteger idx = 1;
if (idx < matchCount) {
tempRange = [match rangeAtIndex:idx++];
YYYY = tempRange.location != NSNotFound ? [timestamp substringWithRange:tempRange] : nil;
}
if (idx < matchCount) {
tempRange = [match rangeAtIndex:idx++];
MM = tempRange.location != NSNotFound ? [timestamp substringWithRange:tempRange] : nil;
}
if (idx < matchCount) {
tempRange = [match rangeAtIndex:idx++];
DD = tempRange.location != NSNotFound ? [timestamp substringWithRange:tempRange] : nil;
}
if (idx < matchCount) {
tempRange = [match rangeAtIndex:idx++];
hh = tempRange.location != NSNotFound ? [timestamp substringWithRange:tempRange] : nil;
}
if (idx < matchCount) {
tempRange = [match rangeAtIndex:idx++];
mm = tempRange.location != NSNotFound ? [timestamp substringWithRange:tempRange] : nil;
}
if (idx < matchCount) {
tempRange = [match rangeAtIndex:idx++];
ss = tempRange.location != NSNotFound ? [timestamp substringWithRange:tempRange] : nil;
}
if (idx < matchCount) {
tempRange = [match rangeAtIndex:idx++];
nn = tempRange.location != NSNotFound ? [timestamp substringWithRange:tempRange] : nil;
}
if (idx < matchCount) {
tempRange = [match rangeAtIndex:idx++];
sign = tempRange.location != NSNotFound ? [timestamp substringWithRange:tempRange] : nil;
}
if (idx < matchCount) {
tempRange = [match rangeAtIndex:idx++];
Zhh = tempRange.location != NSNotFound ? [timestamp substringWithRange:tempRange] : nil;
}
if (idx < matchCount) {
tempRange = [match rangeAtIndex:idx++];
Zmm = tempRange.location != NSNotFound ? [timestamp substringWithRange:tempRange] : nil;
}
}
Run Code Online (Sandbox Code Playgroud)
希望这对某人有帮助!
| 归档时间: |
|
| 查看次数: |
2115 次 |
| 最近记录: |