Converting an ISO 8601 timestamp into an NSDate: How does one deal with the UTC time offset? - nsdate

I'm having trouble converting an ISO 8601 timestamp into an NSDate. I tried to use NSDateFormatter, but I can't get it to work with the UTC time offset that appears on the end of the timestamps. To explain, I would like to convert a timestamp such as the following into an NSDate: 2011-03-03T06:00:00-06:00. My question is: How do I deal with the "-06:00" part? I tried using yyyy-MM-dd'T'HH:mm:ssZ as my date format string but it doesn't work. Any suggestions?

No need to remove the :'s. To handle the "00:00" style timezone, you just need "ZZZZ":
Swift
let dateString = "2014-07-06T07:59:00Z"
let dateFormatter = NSDateFormatter()
dateFormatter.locale = NSLocale(localeIdentifier: "en_US_POSIX")
dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ssZZZZ"
dateFormatter.dateFromString(dateString)
Objective-C
NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
dateFormat.locale = [[NSLocale alloc] initWithLocaleIdentifier:#"en_US_POSIX"];
NSString *input = #"2013-05-08T19:03:53+00:00";
[dateFormat setDateFormat:#"yyyy-MM-dd'T'HH:mm:ssZZZZ"]; //iso 8601 format
NSDate *output = [dateFormat dateFromString:input];
NSLog(#"Date output: %#", output);

In my case I received something like that:
"2015-05-07T16:16:47.054403Z"
And I had to use:
"yyyy'-'MM'-'dd'T'HH':'mm':'ss.SSSZ"

The problem is the : character inside the timezone offset. You could explicitly remove just that colon, or remove all of the colons, and then proceed. For example:
NSString *s = #"2011-03-03T06:00:00-06:00";
s = [s stringByReplacingOccurrencesOfString:#":" withString:#""];
NSDateFormatter *f = [[NSDateFormatter alloc] init];
[f setDateFormat:#"yyyy-MM-dd'T'HHmmssZZ"];
NSDate *d = [f dateFromString:s];
NSLog(#"%#", d);
This logs:
EmptyFoundation[5088:707] 2011-03-03 12:00:00 +0000

Here is the method that I use:
-(NSDate *)dateFromISO8601String:(NSString *)dateString{
if (!dateString) return nil;
if ([dateString hasSuffix:#"Z"]) {
dateString = [[dateString substringToIndex:(dateString.length-1)] stringByAppendingString:#"-0000"];
}
dateString = [dateString stringByReplacingOccurrencesOfString:#":" withString:#""];
NSDateFormatter *dateFormatter = [[[NSDateFormatter alloc] init] autorelease];
dateFormatter.dateFormat = #"yyyy-MM-dd'T'HHmmssZ";
return [dateFormatter dateFromString:dateString];
}

Converting ISO 8601 timestamp into NSDate In Swift:
let dateFormatter = NSDateFormatter()
let inputDate = "2015-06-18T19:00:53-07:00"
dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ssZZZZ" //iso 8601
let outputDate = dateFormatter.dateFromString(inputDate)
println(outputDate!) //optional implicitly
Or optional explicitly:
if let outputDate = dateFormatter.dateFromString(inputDate) {
println(outputDate) //no need !
}

Apple supports a separate format for ISO 8601 format
Objective C
NSISO8601DateFormatter *formater = [[NSISO8601DateFormatter alloc]init];
NSString *string = [formater stringFromDate:[NSDate date]];

Related

how to convert date to string like this "2013-12-23T12:02:01+05:30"

I have string "2013-12-23T12:02:01+05:30"
i want to convert into date but i am getting NSDate nil
here is my code
// Convert string to date object
NSString *dateStr = #"2013-12-23T12:02:01+05:30";
NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
[dateFormat setDateFormat:#"yyyy, MM DD 'T' HH:mm:ss Z"];
NSDate *date = [dateFormat dateFromString:dateStr];
Your string format does not match you date string:
NSString *dateStr = #"2013-12-23T12:02:01+05:30";
NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
[dateFormat setDateFormat:#"yyyy-MM-dd'T'HH:mm:ssZ"];
NSDate *date = [dateFormat dateFromString:dateStr];
In you example date sting there are - used in the date, in the format you are using uses . Also DD will give you the day in the year not in the month. and there is no space after the seconds and time zone offset.
You need to set the correct date format to match with the date string
NSString *dateStr = #"2013-12-23T12:02:01+05:30";
NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
[dateFormat setDateFormat:#"yyyy-MM-dd'T'HH:mm:ssZ"];
NSDate *date = [dateFormat dateFromString:dateStr];

Formatting Date from server time to local time using NSTimeZone and Dateformatter

I am receiving a date/time as a NSString from my server where I am converting that time into a NSDate to the users local time using NSTimeZone. After which I try to reformat this NSDate into a better more readable NSString using the new NSDateFormatter format, however when I try to apply this new format it reverts the resulting dateString back to the original Server time.
I would like to know what I am doing wrong, I would like to show the converted time in the new format.
this is the code I am using
// set date format
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
dateFormatter.dateFormat = #"yyyy-MM-dd HH:mm:ss";
// change time to systemTimeZone
NSTimeZone *timeZone = [NSTimeZone systemTimeZone];
[dateFormatter setTimeZone:timeZone];
NSDate *localTime = [dateFormatter dateFromString:[singleInstanceActivationHistoryDictionay objectForKey:#"ActivationTime"]];
// reformat converted Time to readable format
NSDateFormatter *dateFormat1 = [[NSDateFormatter alloc] init];
[dateFormat1 setDateFormat:#"dd/MM/yy - hh:mm a"];
NSString *dateWithNewFormat = [dateFormat1 stringFromDate:localTime];
NSLog(#"TimeZone - %#", timeZone);
NSLog(#"UTC ServerTime - %#", [singleInstanceActivationHistoryDictionay objectForKey:#"ActivationTime"]);
NSLog(#"UTC to deviceTimeZone - %#", localTime);
NSLog(#"NewFormat - %#", dateWithNewFormat);
This is an example of my output
TimeZone - Pacific/Auckland (NZST) offset 43200
UTC ServerTime - 2013-08-22 01:45:59
UTC to deviceTimeZone - 2013-08-21 13:45:59 +0000
NewFormat - 22/08/13 - 01:45 AM
any help would be greatly appreciated
The NSDateFormatter that reads the date must be set to the timezone that the date you are parsing is in, in your case, it is UTC. The date formatter will then be able to produce an NSDate object (which represents a specific moment in time regardless of timezones). You can then give that NSDate object to another NSDateFormatter that is configured to format dates in a specific time zone.
// set date format
NSDateFormatter *dateParser = [[NSDateFormatter alloc] init];
dateParser.dateFormat = #"yyyy-MM-dd HH:mm:ss";
dateParser.timeZone = [NSTimeZone timeZoneWithName:#"UTC"];
NSDate *specificMomentInTime = [dateParser dateFromString:[singleInstanceActivationHistoryDictionay objectForKey:#"ActivationTime"]];
// reformat converted Time to readable format
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
dateFormatter.dateFormat = #"dd/MM/yy - hh:mm a";
dateFormatter.timeZone = [NSTimeZone defaultTimeZone];
NSString *dateWithNewFormat = [dateFormatter stringFromDate:specificMomentInTime];
NSLog(#"UTC ServerTime - %#", specificMomentInTime);
NSLog(#"NewFormat - %#", dateWithNewFormat);

how to get only date from string?

how to get only date from datetime date value
my code is:
NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
[dateFormat setDateFormat:#"yyyy-MM-dd"];
[dateFormat setDateStyle:NSDateFormatterShortStyle];
lblDateAvailable.text = [dateFormat stringFromDate:[datepick date]];
NSDate *date=[dateFormat dateFromString:lblDateAvailable.text];
NSLog(#"%#",date);
result=2012-08-17 18:30:00 +0000
i want to get only date from string.so plz suggest me.
Convert Date into string and using this method Separated the component and pass the Separated value in your label.
NSArray* components = [yourdatestring componentsSeparatedByString:#" "];

Problems converting a NSDate to a string

This extremely simple task was apparantly very hard...
NSDate *date;
date = [someMethod here];
//I've checked with debugger that the method returns an object of type NSDate.
//The description of date at this point is: "2012-02-02 19:42:00 +0000"
NSDateFormatter *dateFormat;
[dateFormat setDateFormat:#"dd-MM-yy hh:mm"];
NSString *dateString = [dateFormat stringFromDate:date];
dateString is just NIL
Does anyone know what's wrong?
Edit: What i really want to achieve is simply:
NSString *receivedDate = #"2012-02-02T20:42:00+01:00";
NSString *fixedDate = [do some magic]
//value of fixedDate is now: "02-02-12 20:42"
As Anna said you need to allocate an instance of NSDateFormatter because all you get is a NULL ptr, which just ignores the messages setDateFormat and stringFromDate, leaving you with NULL.
But also your format is for hours is incorrect. Refer to Date Formatter reference
This works for me:
NSDateFormatter *df = [[[NSDateFormatter alloc] init] autorelease];
[df setDateFormat:##"dd-MM-yy HH:mm"];
NSString *dateString = [df stringFromDate:date];

ios4 - splitting a date and time from a string into two separate strings

I have a JSON feed coming into my app, one of the fields is a combined date & time string which I need to split into discrete date and time strings for display in a table cell. An example of input from the JSON is:
2012-01-18 14:18:00.
I'm getting a bit confused with the date formatter, and clearly I'm not doing it right - I've tried a number of tutorials but most just seem to show how to format a date.
I've tried something a little like this to get just the time:
NSDictionary *rowData = [self.raceData objectAtIndex:[indexPath row]];
NSDateFormatter *dateFormat = [[[NSDateFormatter alloc] init] autorelease];
[dateFormat setDateFormat:#"h:mma"];
NSDate *raceDate = [dateFormat dateFromString:[rowData valueForKey:#"race_time"]];
NSString *raceTime = [dateFormat stringFromDate:raceDate];
but on output raceTime is just null.
Any help appreciated.
maybe the format should be more like
[dateFormatter setDateFormat:#"yyyy-MM-dd 'at' HH:mm"];
have a look at http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/DataFormatting/Articles/dfDateFormatting10_4.html
might clear things up abit
Right, I have this working - it's probably a bit messy but here's what I did:
NSDictionary *rowData = [self.raceData objectAtIndex:[indexPath row]];
NSDateFormatter *dateFormat = [[[NSDateFormatter alloc] init] autorelease];
[dateFormat setDateFormat:#"yyyy-MM-dd HH:mm:ss"];
NSDate* raceDate = nil;
NSError* dateError = nil;
NSRange dateRange = NSMakeRange(0, [[rowData valueForKey:#"race_time"] length]);
[dateFormat getObjectValue:&raceDate forString:[rowData valueForKey:#"race_time"] range:&dateRange error:&dateError];
[dateFormat setDateFormat:#"HH.mm"];
NSString *raceTime = [dateFormat stringFromDate:raceDate];
I can now output raceTime as a standalone time. I had to use getObjectValue:forString:range:error: to parse the original string to a date before changing the formatting and parsing it again.
As I'm using this in a table I suspect I'll need to use a static formatter so it doesn't slow everything down - if anyone can give a best practice on doing that I'd appreciate it.
If you are sure that the input string format wouldn't change – you might use something similar to:
NSString *date = nil;
NSString *time = nil;
NSDictionary *rowData = [self.raceData objectAtIndex:[indexPath row]];
NSString *raceTime = [rowData valueForKey:#"race_time"];
NSArray *dateParts = [raceTime componentsSeparatedByString:#" "];
if ([dateParts count] == 2) {
date = [dateParts objectAtIndex:0];
time = [dateParts objectAtIndex:1];
}

Resources