Convert ISO 8601 to NSDate - objective-c

I have a timestamp coming from server that looks like this:
2013-04-18T08:49:58.157+0000
I've tried removing the colons, I've tried all of these:
Converting an ISO 8601 timestamp into an NSDate: How does one deal with the UTC time offset?
Why NSDateFormatter can not parse date from ISO 8601 format
Here is where I am at:
+ (NSDate *)dateUsingStringFromAPI:(NSString *)dateString {
NSDateFormatter *dateFormatter;
dateFormatter = [[NSDateFormatter alloc] init];
//#"yyyy-MM-dd'T'HH:mm:ss'Z'" - doesn't work
//#"yyyy-MM-dd'T'HH:mm:ssZZZ" - doesn't work
//#"yyyy-MM-dd'T'HH:mm:sss" - doesn't work
[dateFormatter setDateFormat:#"yyyy-MM-dd'T'HH:mm:ss'Z'"];
[dateFormatter setTimeZone:[NSTimeZone timeZoneWithName:#"GMT"]];
// NSDateFormatter does not like ISO 8601 so strip the milliseconds and timezone
dateString = [dateString substringWithRange:NSMakeRange(0, [dateString length]-5)];
return [dateFormatter dateFromString:dateString];
}
One of my biggest questions is, is the date format I have above really ISO 8601? All the examples I have seen from people the formats of each are slightly different. Some have ...157-0000, others don't have anything at the end.

This works for me:
NSString *dateString = #"2013-04-18T08:49:58.157+0000";
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:#"yyyy-MM-dd'T'HH:mm:ss.SSSZ"];
// Always use this locale when parsing fixed format date strings
NSLocale *posix = [[NSLocale alloc] initWithLocaleIdentifier:#"en_US_POSIX"];
[formatter setLocale:posix];
NSDate *date = [formatter dateFromString:dateString];
NSLog(#"date = %#", date);

There is New API from Apple! NSISO8601DateFormatter
NSString *dateSTR = #"2005-06-27T21:00:00Z";
NSISO8601DateFormatter *formatter = [[NSISO8601DateFormatter alloc] init];
NSDate *date = [formatter dateFromString:dateSTR];
NSLog(#"%#", date);

I also have the native API, which is way cleaner... This is the implementation I got in my DateTimeManager class:
+ (NSDate *)getDateFromISO8601:(NSString *)strDate{
NSISO8601DateFormatter *formatter = [[NSISO8601DateFormatter alloc] init];
NSDate *date = [formatter dateFromString: strDate];
return date;
}
Just copy and paste the method, it would do the trick. Enjoy it!

The perfect and best solution that worked for me is:
let isoFormatter = ISO8601DateFormatter();
isoFormatter.formatOptions = [ISO8601DateFormatter.Options.withColonSeparatorInTime,
ISO8601DateFormatter.Options.withFractionalSeconds,
ISO8601DateFormatter.Options.withFullDate,
ISO8601DateFormatter.Options.withFullTime,
ISO8601DateFormatter.Options.withTimeZone]
let date = isoFormatter.date(from: dateStr);
For further more detail, you can refer to apple's official documentation: https://developer.apple.com/documentation/foundation/nsiso8601dateformatter

Related

How to convert an NString to an NSDate and then set the date to a UILabel

I need to convert the following string into a better readable format:
NSString *deadlineFromTable = #"2012-11-13T22:59:00.000Z";
I would like to convert this into an NSDate, so I can format it.
I tried the following, but I get an incompatible pointer error assigning NSString to NSDate when I try to set it to a UILabel (the last line):
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"dd-MM-yyyy"];
NSDate *dateFromString = [dateFormatter dateFromString:deadlineFromTable];
self.deadlineLbl.text = dateFromString;
Thanks for any help.
You need to use the dateFormatter twice. Once for parsing, and once for formatting your string.
You cannot assign a date as a label text directly.
Set format: yyyy-MM-dd'T'HH:mm:ss.Z and then use
NSDate *date = [dateFormatter dateFromString:dedlineFromTable];
Set format: dd-MM-yyyy and then use
NSString *text = [dateFormatter stringFromDate: date];
You need two dateFormatters.
One to convert from your input string to a date and then one to convert from that date into the Label format you want.
You also need to change the format of the date formatter so it matches your string...
NSDateFormatter *dateStringParser = [[NSDateFormatter alloc] init];
[dateStringParser setDateFormat:#"yyyy-MM-dd'T'HH:mm:ss.Z"];
NSDate *date = [dateStringParser dateFromString:deadlineFromTable];
NSDateFormatter *labelFormatter = [[NSDateFormatter alloc] init];
[labelFormatter setDateFormat:#"dd-MM-yyyy"];
self.deadlineLbl.text = [labelFormatter stringFromDate:date];
That should do it.

Objective-C – NSDateFormatter dateFromString ignore time

If I'm not interested in the time can I ignore it? I.e I have a date string that looks like this #"2012-12-19T14:00:00" but I'm only interested in getting the date (2012-12-19) but if I set NSDateFormatter like [dateFormatter setDateFormat:#"yyyy-MM-dd"]; it will return me a nil NSDate.
An NSDate object will always contain a time component as well, as it is representing a point in time — from this perspective one could argue the name NSDate is misleading.
You should create a date formatter for creating dates from string, set the time to the start of the day and use a second date formatter to output the date without time component.
NSString *dateString = #"2012-12-19T14:00:00";
NSDateFormatter *inputFormatter = [[NSDateFormatter alloc] init];
[inputFormatter setDateFormat:#"yyyy-MM-dd'T'HH:mm:ss"];
NSDateFormatter *outputFormatter = [[NSDateFormatter alloc] init];
[outputFormatter setDateStyle:NSDateFormatterShortStyle];
[outputFormatter setTimeStyle:NSDateFormatterNoStyle];
NSDate *date = [inputFormatter dateFromString:dateString];
//this will set date's time components to 00:00
[[NSCalendar currentCalendar] rangeOfUnit:NSDayCalendarUnit
startDate:&date
interval:NULL
forDate:date];
NSString *outputString = [outputFormatter stringFromDate:date];
NSLog(#"%#", outputString);
results in
19.12.12
while the format — as it is chosen by styling — will be dependent of your environment locale
all date string returns 10 characters for the date, what i mean is the date of todayy will be 2012-11-19
you can easily substring the date and use it as you want:
Example :
NSString* newDate = #"";
newDate = [[NSDate date]substringToIndex:10];
the out put will be : 2012-11-19

Convert Short Zulu format date to NSDate

I am having troubles converting a short Zulu date format to a NSDate Object. I have found some answers for converting Zulu strings but mine looks like:
20111210T1000
And based on my researches, I am trying to do:
NSDateFormatter *f = [[NSDateFormatter alloc] init];
[f setDateFormat:#"yyyyMMdd'T'HHmmss Z"];
NSDate *date = [f dateFromString:[str stringByReplacingOccurrencesOfString:#"Z" withString:#" +0000"]];
[f release];
I've tried many ways but my date is still nil...
How should I set my NSDateFormatter?
Here is a quick fix, in your date string you miss the timezone in the format, you should append (Paris one here) to your string and it should work. Also the format was wrong.
NSDateFormatter* df = [[NSDateFormatter alloc]init];
[df setDateFormat:#"yyyyMMdd'T'SSSZ"];
NSString* str = #"20111210T1000-0100"; // NOTE -0100, GMT +1 Paris zone
NSDate* date = [df dateFromString:str];
NSLog(#"%#", date);

dateFromString returns the wrong date

I have the following code:
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
formatter.dateFormat = #"yyyy-mm-dd";
NSDate *cDate = [formatter dateFromString:thisLine];
NSLog(#"cDate '%#' thisLine '%#'", cDate, thisLine);
NSLog prints:
cDate '2011-01-10 05:07:00 +0000' thisLine '2011-07-10'
while cDate should be '2011-07-10'
Any thoughts?
Thanks
Lowercase mm is for minutes not months, month use uppercase MM:
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
formatter.dateFormat = #"yyyy-MM-dd";
NSDate *cDate = [formatter dateFromString:thisLine];
NSLog(#"cDate '%#' thisLine '%#'", cDate, thisLine);
The NSDate description will always print the date with its own formatting, generally for the +000 time zone. You need to use the date format to get the correctly formatted date and use MM for month not mm.
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
formatter.dateFormat = #"yyyy-MM-dd";
NSDate *cDate = [formatter dateFromString:thisLine];
NSLog(#"cDate '%#' thisLine '%#'", [formatter stringFromDate:cDate], thisLine);
-(NSString*)description
Discussion The representation is not guaranteed to remain
constant across different releases of the operating system. To format
a date, you should use a date formatter object instead (see
NSDateFormatter and Data Formatting Guide)

How to turn a NSString into NSDate?

Ive been racking my brains with no luck. Could someone please tell me how i would convert this string:
"2011-01-13T17:00:00+11:00"
into a NSDate?
The unicode date format doc is here
Also, for your situation, you could try this:
// original string
NSString *str = [NSString stringWithFormat:#"2011-01-13T17:00:00+11:00"];
// convert to date
NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
// ignore +11 and use timezone name instead of seconds from gmt
[dateFormat setDateFormat:#"YYYY-MM-dd'T'HH:mm:ss'+11:00'"];
[dateFormat setTimeZone:[NSTimeZone timeZoneWithName:#"Australia/Melbourne"]];
NSDate *dte = [dateFormat dateFromString:str];
NSLog(#"Date: %#", dte);
// back to string
NSDateFormatter *dateFormat2 = [[NSDateFormatter alloc] init];
[dateFormat2 setDateFormat:#"YYYY-MM-dd'T'HH:mm:ssZZZ"];
[dateFormat2 setTimeZone:[NSTimeZone timeZoneWithName:#"Australia/Melbourne"]];
NSString *dateString = [dateFormat2 stringFromDate:dte];
NSLog(#"DateString: %#", dateString);
[dateFormat release];
[dateFormat2 release];
Hope this helps.
put the T part in single quotes, and check the unicode docs for the exact formatting. In my case, I have something similar, which I do this:
NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
[dateFormat setDateFormat:#"YYYY-MM-dd'T'HH:mm:ss.SSS"];
Again, not exactly the same, but you get the idea. Also, be careful of the timezones when converting back and forth between strings and nsdates.
Again, in my case, I use:
[dateFormat setTimeZone:[NSTimeZone timeZoneWithName:#"America/New_York"]];
Did you try this
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
NSDate *dateT = [dateFormatter dateFromString:str];
Cheers
You might check out TouchTime.
https://github.com/jheising/TouchTime.
It's a direct port of the awesome strtotime function in PHP in 5.4 for Cocoa and iOS. It will take in pretty much any arbitrary format of date or time string and convert it to an NSDate.
Hope it works, and enjoy!
Try using this cocoapods enabled project. There are many added functions that will probably be needed as well.
"A category to extend Cocoa's NSDate class with some convenience functions."
https://github.com/billymeltdown/nsdate-helper
Here's an example from their page:
NSDate *date = [NSDate dateFromString:#"2009-03-01 12:15:23"];