NSDateFormatter: stringFromDate and dateFromString not reversible? - ios

I'm having problems using a custom date formatter with NSDateFormatter to convert a string into a date. Here's a short example that creates a string from today's date but fails to convert this back to an NSDate:
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"Mdyyyy"];
NSString *example = [dateFormatter stringFromDate:now]; // e.g., 10292013
NSDate *reverse = [dateFormatter dateFromString:example]; // nil?
So basically it seems that NSDateFormatter is creating a date string that it itself can't turn back into a NSDate using the same format that created the string.
Using MMddyyyy as the date string works, although I can't see from the documentation (which conveniently only goes up to iOS 6.0) why it would matter:
month M 1..2 09 Month - Use one or two for the numerical month, ....
...
day d 1..2 1 Date - Day of the month
The reason why I'm trying to use Mdyyyy instead of MMddyyyy is because it's closer to what NSDateFormatterShortStyle returns for my current NSLocale (M/d/yy).
Perhaps someone might have some insight here as two what I'm doing wrong, or if I'm wrong in my understanding of how this should work. (I know there are a lot of questions here regarding NSDateFormatter, but I didn't find one that fits my problem.)

Mdyyyy is ambiguous as a string ->date mapping. One cannot tell if "1112013" is Jan 11 or November 1. Hence NSDateFormatter will not allow it for string ->date.

Related

Conversion: NSString to NSDate

This is a really common question, but mine might be unique since I have long decimal places for the seconds.
NSString *timestamp = #"2015-11-06 15:27:34.0000000";
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"yyyy-MM-dd'T'HH:mm:ss zzz"];
NSDate *capturedStartDate = [dateFormatter dateFromString: timestamp];
My capturedStartDate is null.
For the date format, I've tried replacing zzz with Z, a, and removing it completely. I've also tried with and without the 'T'. Does someone know the correct format to retrieve this date from the string?
Your date string doesn't have a time zone in it, so you should remove that Z. Also, you have fractions of a second, too. And there's no T in the date string. So you want
yyyy-MM-dd HH:mm:ss.SSSSSS
This does beg the question as to what time zone that string represents. If it is UTC, you'll want to set the time zone of the formatter, accordingly.
Likewise, you might want to be careful about users with non-Gregorian calendars. See Apple Technical Q&A 1480 regarding setting the locale to en_US_POSIX.

Date conversion from string to NSDate in ios

I have searched over internet for a long time to get this but I can't find the solution. I have received a date string from web services as "22 May 2014", I have to convert into NSDate format for check it with current date. And I have to find out the date from web service is in future or in past time.
The actual problem is that when I convert this using
NSDate *date;
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"dd MMMM YYYY"];
date = [dateFormatter dateFromString:dateString];
But I get an entirely Different Date, Sample Input dateString:22 June 2014 and Output I get is 2013-12-21 18:30:00+0000
Please suggest any solutions.
Thanks in advance. :)
You're using YYYY, which doesn't mean what you think it means. From the TR35-31 documentation, Y is the symbol for "year in week-of-year calendars".
You want dd MMMM yyyy instead as your format string. Mixing week-of-year-based fields and regular day/month/year fields is a recipe for odd problems.
Additionally, you may well want to set the time zone in your formatter - if you're just parsing a date, then you should consider using UTC, and make sure that all your calculations and formatting/parsing use UTC.
(I suspect the issue here is that week-of-year hasn't been set, so is assumed to be 1... and the week-year 2014 started on December 30th. Then the day-of-month is set to 22 by the dd part, and then your time zone offset of UTC+05:30 is taken into account.)

Convert NSString containing AM/PM to NSDate

Maybe it's an old question and I've searched on this site and found some similar questions, but I still cannot solve my problem. I have a NSString named gameDateTimeStr: "11/12/2013-10:00 PM" and I want to convert it to NSDate. I used the following code:
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:#"MM/dd/yyyy-HH:mm a"];
[formatter setLocale:[NSLocale currentLocale]];
NSDate *gameDateTime = [formatter dateFromString:gameDateTimeStr];
However, when printed on consolte, its description is: 2013-11-12 05:00:00 +0000
As you can see, the date is correct, but the time is wrong.
Please help me fix it.
There are one issues with you date formatter, first you are using 24 hour format, HH for the hours in the date format. But you example uses 12 hour format and hh should be used.
[formatter setDateFormat:#"MM/dd/yyyy-hh:mm a"];
Depending on you timezone offset the date is parsed correctly, since date printedby NSLog is is represented in GMT.
When you create a string form the date object use NSDateFormatter you timezone is used to calculate the correct time offset.

NSDateFormatter local date format issue

I have NSDate, and I need to convert it to string.
Usually I use this code:
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:#"MM/dd/yyyy"];
NSString *stringFromDate = [formatter stringFromDate:date];
return stringFromDate;
But I need to show data according to local date format. For instance, in USA the date usually starts from the month, but in Russia the date starts from day (#"dd/MM/yyyy"). And may be there is a different way of separators in different countries: '/', '.' ',' '-'
What is the best approach to do this?
Update (according to Jon Skeet answer):
if I specify NSDateFormatterMediumStyle the date is "4.9.2013", but for me it's better "04.09.2013". NSDateFormatterShortStyle doesn't help with this neither. Is there a way to add zeroes ?
See the date formatter guide which gives advice about this, suggesting that you set the style rather than calling setDateFormat:
NSDateFormatter makes it easy for you to format a date using the settings a user configured in the International preferences panel in System Preferences. The NSDateFormatter style constants—NSDateFormatterNoStyle, NSDateFormatterShortStyle, NSDateFormatterMediumStyle, NSDateFormatterLongStyle, and NSDateFormatterFullStyle—specify sets of attributes that determine how a date is displayed according to the user’s preferences.
It then gives a listing showing an example starting with this:
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateStyle:NSDateFormatterMediumStyle];
[dateFormatter setTimeStyle:NSDateFormatterNoStyle];
It sounds like you'd want NSDateFormatterShortStyle instead though.
setDateFormat is what you use for a custom format. More advice from the same document:
There are broadly speaking two situations in which you need to use custom formats:
For fixed format strings, like Internet dates.
For user-visible elements that don’t match any of the existing styles

Need information on printing [NSDate date]

When I am printing the date
//getting the current date and time
self.date = [NSDate date];
NSLog(#"%#",date);
The date which I am getting is correct, but there is a delay in time by 6 hrs. My system time is correct.
try this
NSLocale* currentLoc = [NSLocale currentLocale];
NSLog(#"%#",[[NSDate date] descriptionWithLocale:currentLoc]);
Make use of NSDateFormatter
NSDate *today = [NSDate date];
//Create the dateformatter object
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
//Set the required date format
[dateFormatter setDateFormat:#"yyyy-MM-dd HH:mm:ss"];
//Get the string date
NSString *dateString = [dateFormatter stringFromDate:today];
//Display on the console
NSLog(dateString);
Logging an NSDate in the debugger is somewhat misleading as it gives you a calendar day and time for a particular time zone - UTC / GMT. However, NSDate has no inherent time zone or any inherent relationship to how humans perceive and think about dates at all. Instead, it is a timestamp. Classes like NSDateComponents, NSTimeZone, NSDateFormatter, and so on all exist to provide human context and formatting.
So what you see is the timestamp formatted to that particular format and UTC time zone, which is how NSDate will always appear when printed in the debugger or the console. If you were to calculate the time zone offset between UTC and your own time zone, you'd find that the date represents the time stamp you gave it, and not one however many hours off.
you can set current time zone for customizing your date format.
This link can help:
https://stackoverflow.com/a/7213629/456471
The default date string representation is probably formatting the date as UTC, rather than your local time zone (the exact format that it will use is not defined, and may change from release to release, so you shouldn't rely on it). You should use the NSDateFormatter class if you need to format a date in a particular format (or with a particular time zone, including the local time zone); see the Data Formatting Guide and the NSDateFormatter Class Reference for more information.

Resources