I have few NSDate
objects which contain values compliant to this format yyy-MM-dd\'T\'HH:mm:ss.SSS
When I try to convert to a different for
The problem is that you are creating string from date with one format and then trying to convert it back to date with different format. To create date from string you should use the same format as you've used to create that string otherwise you'll get nil. If you do need formatted string with other format, then first create date from string with correct format and then convert it back to string with format you want. The issue is the order.
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]);
Other approach is to use different formatters as Jon Skeet suggest just to avoid confusion...
You've got an NSDate
, modelObj.createdDate
, and you want to format it as a string in a certain format, MMM dd, yyyy HH:mm
. You don't need to convert the date to a string and then back to another NSDate
and then back to a string again. If you use the same formatter for both operations, you'll just end up with the same date you started with.
You only need to format the date once, to your final desired appearance:
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:@"MMM dd, yyyy HH:mm"];
NSLog(@"========= REal Date %@",[format stringFromDate:modelObj.createdDate]);
The NSDate
itself is not "compliant to the following format". It has no format -- it's a moment in time, an offset from a reference date. If you NSLog()
it, it will indeed format itself into a human-readable string (probably using a date formatter behind the scenes), but that is just one representation that it chooses.
Right now, you're getting nil
from the second formatting operation, NSDate *formattedDate = [format dateFromString:createdDateStr];
because the format of the string you pass in to the formatter has to exactly match what the formatter expects. In this case, it doesn't, because you created the string using the format yyyy-MM-dd'T'HH:mm:ss.SSS
, but have told the formatter to expect MMM dd, yyyy HH:mm
. The formatter thus can't parse the string, and returns nil
to indicate failure.
EDIT: Rereading your question, I think you've got a conceptual misunderstanding aside from anything else:
I have few NSDate objects which contains values compliant to the following format
As far as I'm aware (I'm not an Objective-C programmer, admittedly) an NSDate
object doesn't know anything about formatting. It just represents an instant in time. It isn't aware of whether it was parsed from text or created in some other way.
It's like an int
- an int
variable isn't in decimal or hex, it's just a number. It's when you format and parse that you specify that. Likewise, you use NSDateFormatter
to describe the format you want at the point of parsing and formatting.
You've currently only got one NSDateFormatter
- you're setting the format to "yyyy-MM-dd'T'HH:mm:ss.SSS"
then resetting it before you've called dateFromString
. The code snippet you've given formats modelObj.createdDate
into ISO-8601 format, but then tries to parse it using the "MMM dd, yyyy HH:mm" format.
I suggest you have two separate NSDateFormatter
objects:
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]);
Note that I've changed your formattedDate
variable to parsedDate
, as that's what it really is - an NSDate
which has been created by parsing text.
As noted in comments, unless you actually need to format and parse like this, you shouldn't. I included all of your original code just to show how you can format a date and then reparse it with the same NSDateFormatter
. You'll get the same result with just:
NSDateFormatter *shortFormat = [[NSDateFormatter alloc] init];
[shortFormat setDateFormat:@"MMM dd, yyyy HH:mm"];
NSLog(@"========= REal Date %@",[shortFormat stringFromDate:modelObj.createdDate]);
In general, you should avoid unnecessary conversions. Convert from text to the more natural data type (NSDate
in this case, but the same applies for numbers etc) and use that data type for as much of your code as possible, only converting to text at the last moment.