我有几个NSDate
个对象,其中包含符合此格式yyy-MM-dd'T'HH:mm:ss.SSS
当我尝试转换为其他格式(例如MMM dd, yyyy HH:mm
时)格式化程序始终返回nil
。
但是,如果我通过NSDate
对象对字符串值进行硬编码,则会将其转换为新格式而不会出现问题。
我使用NSDate
方法填充模型中的setValue:forKey:
对象,我觉得问题出在JSON库传递字符串值的地方。但是,调试显示NSDate
包含通过JSON返回的值。
知道是什么导致了这种奇怪的行为吗?
这是我的转换代码:
NSDateFormatter *format = [[NSDateFormatter alloc] init];
[format setDateFormat:@"yyyy-MM-dd'T'HH:mm:ss.SSS"];
NSString *createdDateStr = [format stringFromDate:modelObj.createdDate];
[format setDateFormat:@"MMM dd, yyyy HH:mm"];
NSDate *formattedDate = [format dateFromString:createdDateStr];
NSLog(@"========= REal Date %@",[format stringFromDate:formattedDate]);
答案 0 :(得分:10)
编辑:重读你的问题,我认为你除了其他任何事情之外还有一个概念上的误解:
我有几个NSDate对象,其中包含符合以下格式的值
据我所知(我不是Objective-C程序员,不可否认)NSDate
对象对格式化一无所知。它只是代表了一个瞬间。它不知道它是从文本中解析还是以其他方式创建。
就像int
- int
变量不是十进制或十六进制,它只是一个数字。这是你格式化和解析时指定的。同样,您使用NSDateFormatter
在解析和格式化时描述所需的格式。
您目前只有一个 NSDateFormatter
- 您在调用之前将格式设置为"yyyy-MM-dd'T'HH:mm:ss.SSS"
,然后重置 dateFromString
。您已将格式为modelObj.createdDate
的代码段转换为ISO-8601格式,但之后尝试使用“MMM dd,yyyy HH:mm”格式解析。
我建议您有两个单独的NSDateFormatter
个对象:
NSDateFormatter *isoFormat = [[NSDateFormatter alloc] init];
[isoFormat setDateFormat:@"yyyy-MM-dd'T'HH:mm:ss.SSS"];
NSString *createdDateStr = [format stringFromDate:modelObj.createdDate];
NSDateFormatter *shortFormat = [[NSDateFormatter alloc] init];
[shortFormat setDateFormat:@"MMM dd, yyyy HH:mm"];
NSDate *parsedDate = [isoFormat dateFromString:createdDateStr];
NSLog(@"========= REal Date %@",[shortFormat stringFromDate:parsedDate]);
请注意,我已将formattedDate
变量更改为parsedDate
,因为它实际上是 - NSDate
已通过解析文本创建。
正如评论中所述,除非您实际需要进行格式化和解析,否则您不应该这样做。我将所有原始代码都包含在内,以显示您如何格式化日期,然后使用相同的NSDateFormatter
重新分析它。你只会得到相同的结果:
NSDateFormatter *shortFormat = [[NSDateFormatter alloc] init];
[shortFormat setDateFormat:@"MMM dd, yyyy HH:mm"];
NSLog(@"========= REal Date %@",[shortFormat stringFromDate:modelObj.createdDate]);
通常,您应该避免不必要的转换。将从文本转换为更自然的数据类型(在这种情况下为NSDate
,但这同样适用于数字等)并尽可能多地使用该数据类型,仅转换在最后一刻发短信。
答案 1 :(得分:4)
问题是您使用一种格式从日期创建字符串,然后尝试使用不同的格式将其转换回日期。要从字符串创建日期,您应该使用与用于创建该字符串相同的格式,否则您将获得nil。如果确实需要具有其他格式的格式化字符串,则首先使用正确的格式从字符串创建日期,然后将其转换回所需格式的字符串。问题是订单。
NSDateFormatter *format = [[NSDateFormatter alloc] init];
[format setDateFormat:@"yyyy-MM-dd'T'HH:mm:ss.SSS"];
NSString *createdDateStr = [format stringFromDate:modelObj.createdDate];
NSDate *formattedDate = [format dateFromString:createdDateStr];
[format setDateFormat:@"MMM dd, yyyy HH:mm"];
NSLog(@"========= REal Date %@",[format stringFromDate:formattedDate]);
其他方法是使用不同的格式化程序Jon Skeet建议只是为了避免混淆......
答案 2 :(得分:1)
您有NSDate
,modelObj.createdDate
,并希望将其格式化为特定格式的字符串MMM dd, yyyy HH:mm
。您不需要将日期转换为字符串,然后再转换回另一个NSDate
,然后再将其转换回字符串。如果您对这两个操作使用相同的格式化程序,那么您最终将得到与开始时相同的日期。
您只需将日期格式化一次,即可达到最终所需的外观:
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:@"MMM dd, yyyy HH:mm"];
NSLog(@"========= REal Date %@",[format stringFromDate:modelObj.createdDate]);
NSDate
本身不符合“以下格式”。它具有 no 格式 - 它是一个时刻,与参考日期的偏移。如果你NSLog()
它,它确实会将自己格式化为一个人类可读的字符串(可能在幕后使用日期格式化程序),但这只是它选择的一种表示形式。
现在,您从第二个格式化操作nil
获得NSDate *formattedDate = [format dateFromString:createdDateStr];
,因为您传入格式化程序的字符串格式必须与格式化程序所期望的格式完全匹配。在这种情况下,它没有,因为您使用格式yyyy-MM-dd'T'HH:mm:ss.SSS
创建了字符串,但已告诉格式化程序期望MMM dd, yyyy HH:mm
。格式化程序因此无法解析字符串,并返回nil
以指示失败。