iOS create NSDate from output of Python datetime.isoformat()? - ios7

My python backend uses the isoformat() method on UTC date times, which results in strings that look like 2014-01-14T18:07:09.037000. Following other examples, I'm trying to create NSDates from those strings (passed up in JSON packets):
NSDateFormatter *dateFormatter = [NSDateFormatter new];
[dateFormatter setDateFormat:#"yyyy-MM-dd'T'HH:mm:S"];
NSLog(#"cycle_base %#", myFields[#"cycle_base"]);
self.cycleBase = [dateFormatter dateFromString: myFields[#"cycle_base"]];
NSLog(#"cycleBase %#", self.cycleBase);
I've tried variants on the S part (which is supposed to be fractional seconds?) of the format string, but to no avail. I always get a nil back. What am I doing wrong?

iOS 7 follows the Unicode Technical Standard #35, which is a list of format patterns.
In this document you will find that the format string for fractional seconds is capitalized S.
NSString *string = #"2014-01-14T18:07:09.037000";
NSDateFormatter *formatter = [NSDateFormatter new];
formatter.dateFormat = #"yyyy-MM-dd'T'HH:mm:ss.S";
NSDate *date = [formatter dateFromString:string];
NSLog(#"%#", date);
This will net you a valid NSDate object. Don't forget to set the proper time zone and locale on your NSDateFormatter object.

Related

Not getting NSDate from string

I have following date in string formate "date string : 2014-09-28 17:30:00"
Now, I want to convert it into NSDate.
I have use following code for this.
NSString *date = #"2014-09-28 17:30:00";
NSDateFormatter *dateFormatter1 = [[NSDateFormatter alloc] init];
[dateFormatter1 setDateFormat:#"yyyy-MM-dd HH:mm:ss"];
NSDate *dateFromString = [[NSDate alloc] init];
dateFromString = [dateFormatter1 dateFromString:date];
NSLog(#"date from string: %#", dateFromString);
I got the following output.
date from string: 2014-09-28 12:00:00 +0000
So, Here Time is changed.
Please tell me, How can I convert into NSDate. What I am missing here?
When you pass an NSDate object into NSLog, it will print the NSDate in GMT time, which may not be your timezone (and why you were getting 12:00 instead of 17:30), this would also cause the output of your NSLog statement to be different for people who are running your code in different timezones, so what you want to do is call the [NSDateFormatter stringFromDate:] method if you want to keep your specified time from your date object:
So replace this line of code:
// Will print out GMT time by default (+0000)
NSLog(#"date from string: %#", dateFromString);
With this line:
// Will honor the timezone of your original NSDate object:
NSLog(#"date from string: %#", [dateFormatter1 stringFromDate:dateFromString]);
And that should print out the value you were hoping for.
// --------------------------//
Note: It is important to understand that NSDate objects do not have any concept of timezones, so it is up to the developer to manage and track their timezones with the provided platform methods.
On iOS, you can look into using this class:
NSTimeZone, which can help you manage/assign your timezone(s) on iOS platforms.
If you are developing for OSX, you can assign a timezone and locale with this method: -descriptionWithCalendarFormat:timeZone:locale:. (Sadly, this method is OSX-only)
Hope that helps.
There is a time zone component attached to your log at the end that means the date is converted to the specified time zone..here greenwhich mean time
So converting into your time locale can give you the right value you inserted
In your first string add +0000 to the end and check again you can see the value is the same you get.ie the conversion is done on the GMT format
visit https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/DataFormatting/Articles/dfDateFormatting10_4.html
This documentation provides you how to convert NSString to date.
this code is provided by apple documentation.
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateStyle:NSDateFormatterMediumStyle];
[dateFormatter setTimeStyle:NSDateFormatterNoStyle];
NSDate *date = [NSDate dateWithTimeIntervalSinceReferenceDate:162000];
NSString *formattedDateString = [dateFormatter stringFromDate:date];
NSLog(#"formattedDateString: %#", formattedDateString);
// Output for locale en_US: "formattedDateString: Jan 2, 2001".
To make string as date
NSString *formattedDateString = [dateFormatter stringFromDate:date];
stringFromDate:
Returns a string representation of a given date formatted using the receiver’s current settings.
what you had used
dateFromString:
Returns a date representation of a given string interpreted using the receiver’s current settings.

NSDateFormatter: Converting "5/13/2012 6:05am" (US, EDT) to "13/05/2012 12:05" (IT, GMT+1)

I am retrieving a time value from a server. The format is:
"5/13/2012 6:05am"
It is not specified in the string but I know it is "EDT".
I need to:
1) Get rid of the am/pm thing.
2) Convert it from EDT (or other timezone) to the local GMT+/-x time.
For my timeZone (Italy, GMT+1) it should become:
"13/05/2012 12:05"
How can I do this with NSDateFormatter?
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setLocale: [NSLocale alloc] initWithLocaleIdentifier:#"en_US"]];
[dateFormatter setDateFormat:#"dd-MM-yyyy HH:mm"];
...?
Thanks
Nicola
First of all, you set your NSDateFormatters dateFormat to the source format. In your case:
[dateFormatter setDateFormat:#"M/d/yyyy h:mma"];
NSDate *myDate = [dateFormatter dateFromString:#"5/13/2012 6:05am"];
This creates a new instance of NSDate. Now you set the formatters dateFormat to your target format:
[dateFormatter setDateFormat:#"dd/MM/yyyy hh:mm"];
NSString *myString = [dateFormatter stringFromDate:myDate];
You could also use two date formatters, one for converting you'r string into NSDate instance and one to convert it back to the corrected NSString.
For further informations and the complete list of the current format specs refer to the unicode reference and the Apple Docs

NSDateFormatter producing (null) SQLite and iOS 5.1

Maybe somebody can help explain why I am getting a null value when converting a string to a date. It all looks right but I'm obviously missing something here.
Some background:
This iPad app will be used in different countries and I will need to do a calculation on the date to see if 90 days have passed since a user last logged in.
I have a SQLite Database with a DateLastIn field set as TEXT
My Object has a DateLastIn property set as NSDate
When populating my record object I set up a NSDateFormatter as such..
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:#"yyyy-MM-dd hh:mm:ss"]; // SQLite default date format
Then I read in the DateLastIn (Using FMDB wrapper for SQLite).
// test SQLite as String
NSString *testDate = [results stringForColumn:#"DateLastIn"];
NSLog(#"DateLastIn straight from DB (string) shows %#", testDate);
Result:
DateLastIn straight from DB (string) shows 2012-04-23 18:20:51
All is good so far. Next I test converting this to an NSDate object e.g
NSDate *aDate = [[NSDate alloc] init];
aDate = [formatter dateFromString:testDate];
NSLog(#"Using formmater on string date results in: %#", aDate);
Result:
Using formmater on string date results in: (null)
I have tried DATETIME in SQLite, I've tried using NSString in my object instead of NSDate and seem to be going around in circles.
Any help much appreciated.
NSDateFormatter uses the format patterns from the Unicode Technical Standard #35.
For the hour format, you need HH (Hour [0-23]) not hh (Hour [1-12]).
I changed your date format to HH not hh and it works. Here is my test code....
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:#"yyyy-MM-dd HH:mm:ss"]; // SQLite default date format
// test SQLite as String
NSString *testDate = #"2012-04-23 18:20:51";
NSDate *aDate = [formatter dateFromString:testDate];
NSLog(#"Using formmater on string date results in: %#", aDate);

Why isn't my time zone being saved into my NSDate?

I must initialize an NSDate object from NSString in objective-c. I do it like this:
NSString *dateString = [[webSentence child:#"DateTime"].text stringByReplacingOccurrencesOfString:#"T" withString:#" "];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"yyyy-mm-dd HH:mm:ss"];
[dateFormatter setTimeZone:[NSTimeZone timeZoneWithName:#"Europe/Budapest"]];
NSDate *date = [[NSDate alloc] init];
date = [dateFormatter dateFromString:dateString];
E.g: when I try it with string value #"2011-01-02 17:49:54" I get an NSDate 2011-01-02 16:49:54 +0000. As you can see there is a one hour difference between the two values. NSDate has a wrong value, it should be exactly the same I defined in my string in the timezone I set in dateFormatter. It seems it uses my date defined it string as UTC, even if I set its timezone to "Europe/Budapest". How can I fix this problem?
Thanks!
NSDate stores dates relative to a standard reference date. From the class docs:
"The sole primitive method of NSDate, timeIntervalSinceReferenceDate, provides the basis for all the other methods in the NSDate interface. This method returns a time value relative to an absolute reference date—the first instant of 1 January 2001, GMT."
NSDate does not itself have any concept of time zones. So the NSDateFormatter did the right thing: it converted a date which you told it had a GMT offset (by specifying a time zone), and gave you a "normalized" NSDate for that date.
If you want to see the date represented in the Europe/Budapest time zone, either use your existing date formatter (-stringFromDate:) or the appropriate NSDate description method (e.g. -descriptionWithCalendarFormat:timeZone:locale:).
P.S.- You don't need an alloc/init at all in your code as written. In non-ARC that would be a leak.
P.P.S.- Your date format is incorrect and giving nonsensical results. I've gone ahead and cleaned up your code as follows (tested under ARC):
NSString *dateString = #"2011-09-02 17:49:54";
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
NSTimeZone *tz = [NSTimeZone timeZoneWithName:#"Europe/Budapest"];
[dateFormatter setDateFormat:#"yyyy-MM-dd HH:mm:ss"];
[dateFormatter setTimeZone:tz];
NSDate *date = [dateFormatter dateFromString:dateString];
NSLog(#"%#", [dateFormatter stringFromDate:date]);
NSLog(#"%#", [date descriptionWithCalendarFormat:nil timeZone:tz locale:nil]);
Two things:
1) you have an error in your date format string. You should use MM for month, not mm (lowercase mm is for minutes)
2) after you create you NSDate object, you'll need to use the NSDateFormatter method stringFromDate: to generate a date string localized to a particular timezone. If you just do a straight NSLog() on the NSDate object it will show the date as GMT by default (GMT is one hour behind Budapest time)

How do I convert from NSString to NSDate using NSDateFormater

I have this string: 2012-01-12T21:01:00 and this code:
NSDateFormatter *df = [[NSDateFormatter alloc] init];
[df setDateFormat:#"yyyy-MM-dd hh:mm:ss a"];
NSDate* arrivalTime=[df dateFromString:field_arrival_time];
But it returns nil. What date format should I use to parse this string?
Your string 2012-01-12T21:01:00 contains the literal T (At least I believe it's a literal, it doesn't appear to signify a timezone). You must include this in your date format.
[df setDateFormat:#"yyyy-MM-dd'T'hh:mm:ss"];
Note the lack of the a in the date format, using it will require your input string to use AM or PM preceded by a white space. For more information on special characters with NSDateFormatter take a look at the Date Formatting Guide paying extra attention to the Fixed Formats.
Edit: Your input string does not specify a timezone, it will probably be interpreted as UTC and be localized to the timezone of your machine when you output it through NSLog().
I have tried a lot on your string but never get result. only nil shows on console. but when i remove character "T" from your string it gives perfect result.
[f setDateFormat:#"yyyy-MM-dd HH:mm:ss"];
NSDate *date = [f dateFromString:#"2012-01-12 21:01:00"];
NSLog(#"date %#", date);
NSDateFormatter *f2 = [[NSDateFormatter alloc] init];
[f2 setDateFormat:#"dd-MM-yyyy"];
NSString *s = [f2 stringFromDate:date];
NSLog(#"S %#", s);
/// OutPut : S 12-01-2012