NSDateformatter Converting date to string - objective-c

I am having the following date and time 2013-04-25 10:42:44 +0000. When i convert the above date to string, i am getting the output as 2013-04-25 16:12:44. Following is the code i am using to convert the date to string
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc]init];
dateFormatter.timeZone = [NSTimeZone systemTimeZone];
[dateFormatter setDateFormat:#"yyyy-MM-dd HH:mm:ss"];
NSString *dateStr= [dateFormatter stringFromDate:date]];
NSLog(#"dateStr--%#",dateStr);

This gets asked over and over (but is difficult to find via search).
When you log an NSDate object, you will always get the date in UTC format. This is how the description method of NSDate is currently implemented.
As long as the difference you are seeing can be accounted for based on your local timezone relative to UTC, then what you are seeing it correct and expected behavior.
BTW - there is no reason to set the date formatter's timezone to the "system" timezone. This is already done by default. Same for the locale. Only set the timezone or locale if you want something different from the current values.

I guess it's a timezone issue. Set your formatters time zone to GMT:
dateFormatter.timeZone = [NSTimeZone timeZoneForSecondsFromGMT:0];

I assume the variable date gets initialized via [NSDate date].
Maybe the quite extensive answer in the follwing topic is helpful here, too.
Does [NSDate date] return the local date and time?

Related

Objective-c NSDateFormatter timezone reverts to GMT

I am playing about with some timezone calculations and I have noticed quite an annoying error which is causing me problems.
If I create a date, use NSDateformatter to convert it to a certain time zone, retrieve that string, and then use dateformatter to convert the string back into a date object, it keeps reverting to my local GMT time.
Example
NSDate *date = [NSDate date];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"yyyy-MM-dd HH:mm:ss zzz"];
[dateFormatter setTimeZone:[NSTimeZone timeZoneWithAbbreviation:#"COT"]];
NSString *str = [dateFormatter stringFromDate:date];
NSLog(#"%#", str);
//prints 2015-02-04 10:33:45 GMT-5
NSDate *newDate = [dateFormatter dateFromString:str];
NSLog(#"%#", newDate);
//Prints 2015-02-04 15:33:45 +0000
Why does it keep reverting back to GMT? I need that date object to accurately reflect the time zone I have set the dateformatter to for some testing purposes, so this is quite a frustrating issue.
Any help would be much appreciated
I believe that the problem is that NSDate itself (i.e. the value you're logging at the end) doesn't have a time zone - it's just a moment in time. You're specifying the time zone *when formatting the value using stringFromDate*, and you're still using that when you *parse* the value back to anNSDate... but theNSDate` value itself doesn't remember the time zone.
To give a different example, imagine you had an IntegerFormatter for NSInteger, which let you say whether you wanted to format and parse in hex or decimal. You could format the decimal value 16 to 0x10, and then parse that value back... but the NSInteger wouldn't "remember" that it was parsed from hex. It's exactly the same here - the time zone plays a part in the parsing (at least when the value itself doesn't specify the time zone) but it isn't part of the result in itself.
I need that date object to accurately reflect the time zone
Then you need to keep the time zone separately alongside the NSDate, basically... (Looking at the documentation, it sounds like NSCalendarDate did what you want, but that's deprecated.)

Convert to NSDate from NSString: How to ignore the timezone

I am converting an NSString with a date format of 2012-06-30 into an NSDate using the following code:
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"yyyy-MM-dd"];
NSDate *date = [dateFormatter dateFromString:dateString];
When omitting [dateFormatter setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0]] the value in NSString is 2012-06-29 23:00:00 plus some automatically added time zone information, which indicates that the the system has some assumptions about the current time zone.
The conversion works fine when I set the time zone with the method above.
However, what would happen if the user is in a different time zone?
How can I make sure that iOS parses just the date as it is and does not add any time information?
The data will not change, timezones dont affect that date itself, it just affect the date presentation, so a date that says 13:00 GMT will have the same presentation of a date that is 14:00 GMT +1
You shouldnt care about the timezones, instead for date conversion to the current time zone of the device use
[dateFormatter setTimeZone:[NSTimeZone systemTimeZone]];
This will set the time zone of the device

Wrong time with NSDate and NSTimezone

I have two dates (written in two different NSString), for example
31/12/2011
and
31/03/2012
I have to check if today is in this range.
For read the date from the NSString, I'm doing this:
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"dd/MM/yyyy"];
[dateFormatter setTimeZone:[NSTimeZone systemTimeZone]];
NSDate *mydate = [dateFormatter dateFromString:my_string];
NSLog(#"%#", mydate);
but, in this example, the log is this one
2011-12-30 23:00:00 +0000
2012-03-30 23:00:00 +0000
So it's one hour behind.
I know that using
NSString *string = [dateFormatter stringFromDate:my_date];
my string it will be ok, but I can't see if today is in the range using NSString (or not?)!
So I have to use NSDate, but how can I solve the "time zone" problem?
Also, I have this problem also using
[NSDate date];
It returns me one hour ago (and I don't want it, because if someone check at midnight, for the phone it will be the day before!)
The following should help:
[dateFormatter setTimeZone:[NSTimeZone timeZoneWithName:#"EST"]];
for more details, please check out This question ... It looks similar. The "EST" can be replaced with whichever time zone is required.
I may be mistaken, but it looks, like you don't need to take care about time zones in this case. If you have just dates in format dd/MM/yyyy, when you will parse it with NSDateFormatter, it will use current timezone by default. So, when you will be comparing with your today's date all 3 dates will be in the same timezone and date/time adjusting will not be performed.

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?

Keep original time zone with NSDateFormatter

I have strings like 2011-01-19T20:30:00-5:00 and I'd like to parse them into an NSDate but I want to keep the original time zone.
NSDateFormatter *dateFormatter = [NSDateFormatter new];
[dateFormatter setDateFormat: #"yyyy-MM-dd'T'HH:mm:ssZ"];
NSLog(#"%#", [dateFormatter dateFromString: dateString]);
[dateFormatter release];
That snippet gives me 2011-01-20 02:30:00 +0100 which is also correct but I wish to keep the original time zone -0500 instead of my local time zone +0100 in the NSDate.
First of all, you should be aware that NSDate objects don't store anything related to their locales or timezones, and internally they're essentially represented as a number of seconds since the first instant of 1 January 2001, GMT.
If you are able to the timezone for the string in an NSTimezone object, just do the following before doing dateFromString:
[dateFormatter setTimeZone:timezoneForString];
and you'll be set.
If you're unable to get an NSTimezone and all you have is a string "2011-01-19T20:30:00-5:00", there isn't a very good way to get to an NSTimezone from the -5:00, since there isn't always an unambiguous way to get a timezone ID (e.g., "America/Los_Angeles") or timezone name (e.g., "Pacific Daylight Time") from an UTC offset. So you'd have to write your own code to manually extract the offset, store it, and add it to the time before displaying it.