NSDates changed in UITableView Header - objective-c

So I am using an array of dates as Section Headers in my UITableView. The dates of my data in the arrays is as follows
07/12/2012
07/13/2012
07/14/2012
But when I run the app the section headers are all moved back one day so they are as follows:
07/11/2012
07/12/2012
07/13/2012
What gives? The data I am pulling from the server is specific to timeZone. We know when our app will be used and on what day (think traveling circus).
I am sure this has to do with NSTimeZone, so I tried the following, which did not work.
self.sectionDateFormatter = [[NSDateFormatter alloc] init];
[self.sectionDateFormatter setDateStyle:NSDateFormatterLongStyle];
[self.sectionDateFormatter setTimeStyle:NSDateFormatterNoStyle];
[self.sectionDateFormatter setTimeZone:[NSTimeZone localTimeZone]];
Anyone know have a solution?

Set the dates to UTC and it fixed the issue.

Related

NSDateFormatter dateFromString returns incorrect date [duplicate]

This question already has answers here:
Get NSDate from NSDate adjusted with timezone
(2 answers)
Closed 9 years ago.
I am trying to use NSDateFormatter in my app which takes a date string and formats it to an NSDate so that I can do Date Comparisons, however I am finding when I use dateFromString and format it the date is losing one day.
NSString *dateString = #"02-06-2012";
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"dd-MM-yyyy"];
NSDate *dateFromString = [[NSDate alloc] init];
dateFromString = [dateFormatter dateFromString:dateString];
NSLog(#"My Date = %#", dateFromString);
[dateFormatter release];
This outputs to the console:
My Date = 2012-06-01 23:00:00 +0000
Try adding this lines to your code,
[dateFormatter setTimeZone:[NSTimeZone timeZoneWithAbbreviation:#"GMT+0:00"]];
or
[dateFormatter setTimeZone:[NSTimeZone timeZoneWithName:#"GMT"]];
SWIFT update :
Code from quetion,
let dateString = "02-06-2012"
var dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "dd-MM-yyyy"
var dateFromString : NSDate = dateFormatter.dateFromString(dateString)!
println("My Date \(dateFromString)")
And Solution ,
dateFormatter.timeZone = NSTimeZone(name: "GMT")
OR
dateFormatter.timeZone = NSTimeZone(abbreviation: "GMT+0:00")
I don't believe that Dhruv's answer is correct. In fact, it's not clear there's any problem at all. You just seem to have an incorrect expectation of what should happen and/or interpretation of what's happening.
NSDate represents a moment in time. This moment does not have one unique name. It will be known by different names in different places and under different naming systems (time zones, calendars). NSDate doesn't deal with any of this, except lamely in its -description method, where it has to produce a string representation of that moment.
Second, a string like "02-06-2012" doesn't specify a precise moment in time. First of all, it's just a date with no time information, so NSDateFormatter just defaults to the first moment for that date. Second, it doesn't specify the time zone. The first moment of the calendar day is a different moment in each time zone. Unless you specify a time zone with -setTimeZone: or the string itself carries time zone information, NSDateFormatter assumes that any date strings you ask it to parse are in the current time zone.
So, your dateFromString object represents the first moment of the specified date, 02-06-2012, in your time zone. I expect this is what you wanted. However, you then got confused by the way that NSDate describes itself when logged. As I said, NSDate has to pick some "name" (string representation) for the moment it represents and which name it picks is fairly arbitrary. These days it is picking the name that the moment is known by in UTC. I gather from the log output shown in your question that you are located at UTC+0100. So, the date may look like it's one day earlier but it really is the same moment you specified. In other words, "2012-06-01 23:00:00 +0000" and "2012-06-02 00:00:00 +0100" are two equivalent names for exactly the same moment in time. You just aren't used to seeing the first one and misinterpreted it.
The lesson is that you have to stop relying on NSDate's self-description to be in any particular time zone. Really, you have to not rely on anything about it, since it's not documented. In fact, the docs for -[NSDate description] state, "The representation is not guaranteed to remain constant across different releases of the operating system."
Dhruv's solution seems to help merely because it causes NSDateFormatter and -[NSDate description] to agree on the time zone. But that's unreliable. It wouldn't work on Snow Leopard, for example, because -[NSDate description] used the local time zone instead of UTC in that version of the frameworks.
More importantly, though, it alters the actual moment represented by the NSDate object you get from NSDateFormatter's interpretation of your date string. I suspect you really want that to have a specific meaning – you want the string to be interpreted as being in the local time zone – and his solution thwarts your intent.
tl;dr: you were getting the date you wanted all along; don't rely on -[NSDate description]; don't use Dhruv's solution

Customising Date Picker in Xcode

How can I customize a UIDatePicker to only show the month and year? There's an existing mode that shows the day, month, and year, but I'd like to get rid of the day portion.
Simply put, you can't. UIDatePicker does not have any API for only showing years and months.
You therefore have 3 possible recourses:
Make your own out of a UIPickerView
Use a UIDatePicker in Date mode and just ignore the day portion
File a bug asking for this capability and hope it gets added at some point
I vote for #1 and #3.
It is not Possible to customize the date picker like you need in the nib file.You can set the mode in nib to get only date or time or both.In this case you need to format your date to the required format using dateFormatter.For this you can set the format to "yyyy-MMM",which will returns you the year and month.
eg:
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"yyyy-MMM"];
NSString *formattedDate = [dateFormatter stringFromDate:date];
[dateFormatter release];

NSDate is 5 hours off

I run the following code:
NSDate *now = [NSDate date];
NSLog(#"now: %#", now);
and get :
2011-09-16 16:14:16.434 iSavemore[1229:7907] now: 2011-09-16 21:14:16 +0000
As you can see i'm running this at 16:14:16 (4:14 pm) but NSDate is returning 21:16:16 (9:14 pm!). Is this an Xcode4 issue or NSDate issue?
NSDate defaults to the Universal timezone (aka GMT).
I'm guessing you're somewhere on the East Coast, 5 hours behind UTC.
Try adding this to your date formatter...
NSDateFormatter *dateFormatter = [[[NSDateFormatter alloc] init] autorelease];
[dateFormatter setLocale:[NSLocale currentLocale]];
...and you should see your local time.
If you want to use a specified locale, rather than 'currentLocale', create a NSLocale for the relevant locale.
NSLocale *usLoc = [[NSLocale alloc] initWithLocaleIdentifier:#"en_US"];
[dateFormatter setLocale:usLoc];
...actually that's US (so possibly not Central).
More specific timezone help can be found here...
http://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/NSDateFormatter_Class/Reference/Reference.html
However, if you want to show expiry time, wouldn't you still want it in the user's currentLocale?
If you look at the output you'll see that the log includes the timezone:
2011-09-16 16:14:16.434 iSavemore[1229:7907] now: 2011-09-16 21:14:16 +0000
^^^^^^
The time stamp of your log is local time. I assume you're in a timezone that is 5 hours ahead of UTC.
A NSDate refers to a particular point in time. It's up to you to display this however you want; usually with an NSDateFormatter.
This is the reason why you'll see plenty of recommendations against storing a time, or a date as anything other than an NSDate. If you try and store it as a string you'll run into a lot of trouble later on when trying to handle the display in different timezones.
Try setting the time-zone of your NSDate to one that is fitting your need, for example [NSTimeZone localTimeZone]
Just a wild guess here, but maybe it has something to do with time zones?

Date/Time parsing in iOS: how to deal (or not deal) with timezones?

I have an ASP.NET MVC 3 website that communicates with my iOS app via JSON. As part of the objects sent in the JSON response, I have dates in the format of yyyy-MM-dd HH:mm:ss ZZZ which outputs 2011-04-05 16:28:22 -07:00. How do I parse that in iOS?
This is the code I'm messing around with right now:
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"yyyy-MM-dd'T'HH:mm:ssZZZ"];
[dateFormatter setTimeZone:[NSTimeZone localTimeZone]];
NSDate *date = [dateFormatter dateFromString:#"2011-04-05T16:28:22-0700"];
NSLog(#"%#; %#; %#", dateFormatter, date, [NSTimeZone localTimeZone]);
First thing to note is that 2011-04-05 16:28:22 -07:00 has to look like 2011-04-05T16:28:22-0700, where a T replaces the first space (assuming that stands for time, or where the time part of the string starts from?), the second space is removed and the colon in the time zone is removed. I figure I'll find a way to format the string that .NET is sending back to conform to the string iOS will parse.
The real issue is that the date that is outputted is 7 hours ahead of what I've sent in the JSON response. So, iOS outputs 2011-04-05 16:28:22 -07:00 as 2011-04-05 23:28:22 +0000, and that is wrong as far as my app is concerned.
The only solution I've found so far is to send the date in the JSON as 2011-04-05 16:28:22 +00:00, but that again is wrong because I'm altering what the real date should be.
Anyway, I'd appreciate someone taking a look and letting me know how I can parse the date string .NET is outputting via the format yyyy-MM-dd HH:mm:ss ZZZ (which I suppose can be re-written to yyyy-MM-ddTHH:mm:ssZZZ) to an NSDate object I can use in iOS.
I don't know how right this is, but I ultimately found that in .NET I have to do DateTime.ToUniversalTime().ToString("yyyy-MM-ddHH:mm:ss") and on the iOS side I have to do this:
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setTimeZone:[NSTimeZone timeZoneWithName:#"UTC"]];
[dateFormatter setDateFormat:#"yyyy-MM-ddHH:mm:ss"];
NSDate *date = [dateFormatter dateFromString:#"2011-04-0600:28:27"];
Only then is the date correct when NSLog outputs, so I'm assuming that I've finally got a proper date/time.
Your iOS date parsing code is correct: 2011-04-05 16:28:22 -07:00 and 2011-04-05 23:28:22 +0000 represent the same time, just in different time zones. Your only problem is that NSDate doesn't actually store the time zone, and so [date description] outputs using UTC.
You're almost certainly better off just using UTC time everywhere for interchange and not bothering with time zones. I'm sure you can get that your ASP.NET code to do that, and it's easier to parse on the receiving end as well. NSDateFormatter uses standard Unicode date formatting syntax, which you can read about here.

Problem formatting NSDate & NSString while using GData-Objectivec-client

I'm fighting with a strange situation: same code works different in two different projects. The one project is just empty command line utility with this code. The second project is with linked gdata-objectivec-client library.
Here is the code:
static NSString * const dateFormat = #"MM/dd/yyyy HH:mm:ss Z";
NSString *tmp_string = #"03/08/2011 10:07:36 +0300";
NSDateFormatter *dateFormatter = [[[NSDateFormatter alloc] init] autorelease] ;
[dateFormatter setLocale:[[[NSLocale alloc] initWithLocaleIdentifier:#"en_US_POSIX"] autorelease]];
[dateFormatter setDateStyle:NSDateFormatterMediumStyle];
[dateFormatter setDateFormat: dateFormat ];
NSDate *newDate = [dateFormatter dateFromString: tmp_string];
NSLog(#"dateFromThatString: %#", newDate);
In just command line utility the result is same
"03/08/2011 10:07:36 +0300"
.
But in the project with gdata-objectivec-client linked to it, the result is changed to
"03/08/2011 07:07:36 +0000"
I cant find what's the problem, any suggestions?
Reading about this subject i've learned that "NSDate is not aware of time zones, it always stores dates in a time zone independent manner (as a span of time since a specific reference date)", so those two NSDate objects representing two different strings in two different projects are the same, there is just some problem in difference between description of NSDate objects, so.. it's not a big problem for future work, because i needed these description only for an easy debug. I will just not use description method, but [NSFormatted stringFromDate:].
It's interesting how gdata-objectivec-client influenced on a project, that description of nsdate obj returns same time, but responding to +0000 gmt offset.
But it's only for discussion.
It looks like the date formatter has different time zones in each case. You can change the time zone using -[NSDateFormatter setTimeZone:].