I have a simple question but it is driving me nuts. I am using an API, and I get a JSon object back, and one of the fields is a date. The date is formatted like this: 2013-05-17T02:00:00.000Z. I cannot seem to get the NSDateformatter correct for this date. Would anyone be willing to give me a hand?
If it is not clear, I am using objective c for an iPhone app. My goal is to get a NSDate object at the end of this. Thanks again for your help.
That's one of the ISO 8601 formats. Parsing it with NSDateFormatter can be tricky at best, which is why I wrote an NSFormatter subclass specifically for parsing and unparsing any ISO 8601 format.
You'll want to get the correct format for that string.
Then you should be able to do something like:
NSString * dateString = jsonDict[#"dateKey"];
NSDateFormatter *df = [[NSDateFormatter alloc] init];
[df setDateFormat:#"yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"]
NSDate *date = [df dateFromString:dateString];
The T is in there to separate date from time and the Z specifies Zulu time. (https://stackoverflow.com/a/8405125/1074558)
Related
I am getting a time/duration from a .NET web service in this format: PT12H30M
How can this be handled?
When you define the format string for parsing a date you use the UTS #35 Date Format Patterns to define what the incoming data looks like. PT looks like a legitimate timezone abbreviation. You will want to fiddle with this depending on whether the minutes and hours are zero-padded or not.
NSString *dateString = #"PT12H30M";
dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"ZZhh'H'mm'M'"];
NSDate date = [dateFormatter stringFromDate:dateString];
Take a look at NSDateFormatter, which can parse dates with a user-specified format using particular syntax. Parse result is a standard NSDate.
Create an instance of NSDateFormatter configured with a format string the describes the time format, and then use the -dateFromString: method to translate the time you get from the web service into a NSDate object.
According to this site:
http://iosdevelopertips.com/cocoa/date-formatter-examples.html
there is a class that handles formatting, which takes in a set of constants/enums (e.g. NSDateFormatterShortStyle) to the "setDateStyle" property/method.
Somehow the NSDateFormatter knows to retrieve the proper locale-specific date format. What I want is to be able to retrieve the default formats based on the user's choice of region format. I have a feeling it is stored in NSLocale, but that does not seem to expose anything that will retrieve the format strings.
Is there a way to extract the formats? It has to be in memory somewhere; I'm hoping the retrieval mechanism is exposed somewhere.
I've looked in several places, but the only answers I get are a lesson on how to create an NSDate from a custom format.
NSDateFormatter *df = [[NSDateFormatter alloc] init];
[df setDateStyle:NSDateFormatterShortStyle];
NSString *dateFormat = [df dateFormat];
NSLog(#"Date format: %#", dateFormat);
[df release];
Just tested on OS X but this should also work in iOS.
How can I parse this into an objective-c NSDate most efficiently?
"2010-07-13T11:22:33-07:00"
This is what I tried
NSDateFormatter *format = [[NSDateFormatter alloc] init];
[format setDateFormat:#"yyyy-MMM-dd'T'HH:mm:ssZ"];
but did not work
have a look here, i had that issue
"The format that I am being given is halfway between RFC 822 and GMT. if i change the "+00:00" to "+0000" then I can use the "Z" on my format. and if i change it to "GMT+00:00" then I can use ZZZZ to get the data properly. It seems that something has been stripped out to handle this hybrid as it was working for me before with OS 3.x"
I store my NSDates to a file in the international format you get when you call description on a NSDate.
However, I don't know how to go back from the string-format to an NSDate object. NSDateFormatter seems to be limited to a couple of formats not including the international one.
How should I go back from the string-format?
Jeff is right, NSCoding is probably the preferred way to serialize NSDate objects. Anyways, if your really want/need to save the date as a plain date string this might help you:
Actually, NSDateFormatter isn't limited to the predefined formats at all. You can set an arbitrary custom format via the dateFormat property. The following code should be able to parse date strings in the "international format", ie. the format NSDate's -description uses:
NSDateFormatter* dateFormatter = [[[NSDateFormatter alloc] init] autorelease];
dateFormatter.dateFormat = #"yyyy-MM-dd HH:mm:ss ZZZ";
NSDate* date = [dateFormatter dateFromString:#"2001-03-24 10:45:32 +0600"];
For a full reference on the format string syntax, have a look at the Unicode standard.
However, be careful with -description - the output of these methods is usually targeted to human readers (eg. log messages) and it is not guaranteed that it won't change its output format in a new SDK version! You should rather use the same date formatter to serialize your date object:
NSDateFormatter* dateFormatter = [[[NSDateFormatter alloc] init] autorelease];
dateFormatter.dateFormat = #"yyyy-MM-dd HH:mm:ss ZZZ";
NSString* dateString = [dateFormatter stringFromDate:[NSDate date]];
Instead of saving the description to a file, why not save the object itself? NSDate conforms to the NSCoding protocol; saving the object means you don't have to worry about translating it. See the NSCoding protocol reference for more information.
I would try to set up an NSDateFormatter to successfully parse the string by the following method:
- (NSDate *)dateFromString:(NSString *)string
Note that it could take you a while to get the NSDateFormatter set up just right to successfully parse your string.
If you're going to store program-facing data like this I would also recommend storing it in an easier-to-access format, e.g., CFAbsoluteTime. Once you have it in your program you can format it into the international format or something else human-readable.
Convert it to a format NSDate accepts and then perform the conversion back.
Alternatively, depending on which NSDate you're referring to (!) initWithString should cover international standard dates.
For PDT, I would want "-0700".
I'm getting a date in the past to determine how long ago something happened.
NSDate *then = [NSDate dateWithString:#"1976-04-01 12:34:56 -0700"]; // Note the hard-coded time zone at the end
I'll be constructing the date string elsewhere but I don't know how to access the local time zone.
I read the Apple Dates and Times Programming Topics for Cocoa as well as the NSTimeZone and NSDate Class References but it's just too hard for me to put the information together. I could really use a few lines of code just to show how it's used.
Update: While struggling with this, I was writing code using a Command Line template so I could try things quickly. I just tried my previous code on iPhone and I'm getting NSDate may not respond to '+dateWithString:' Sorry if that added to the confusion, who knew Apple would change up such a basic class.
Use NSDateFormatter to build NSDate from a string:
NSDateFormatter *inputFormatter = [[NSDateFormatter alloc] init];
[inputFormatter setDateFormat:#"yyyy-MM-dd HH:mm:ss Z"];
NSDate *formatterDate;
formatterDate = [inputFormatter dateFromString:#"1976-04-01 12:34:56 -0700"];
NSString *dateString = [inputFormatter stringFromDate:formatterDate];
NSLog(#"date:%#", dateString);
This way you get the local time from string, for example the date specified by the string:
"1976-04-01 12:34:56 -0700"
is in time zone -0700, (I'm in time zone GMT +1000) so I get:
2009-11-17 22:13:46.480
cmdline[10593:903] date:1976-04-02
05:34:56 +1000
The time zone offset is dependent on the date in much of the world—those parts of it that use Daylight-Saving Time/Summer Time.
The only correct way is to generate the entire string from date and time-zone together. Use NSDateFormatter for this.
The best way is to probably use a simple calendar formatter
NSCalendarDate * date = [NSCalendarDate calendarDate];
[date setTimeZone:[NSTimeZone timeZoneWithAbbreviation:#"PDT"]];
NSLog([date descriptionWithCalendarFormat:#"%z"]);
which will output '-0700'
or leave out the second line if you want the current time zone of the system (not sure which you were asking for)