iOS NSCalendar NSTimezone daylight saving time confusion [duplicate] - ios

I am trying to convert the following string into an NSDate object:
NSString *str=#"25 May 2012 10:25:00";
NSDateFormatter *dateFormatter = [[[NSDateFormatter alloc] init] autorelease];
[dateFormatter setDateFormat:#"d MMM yyyy HH:mm:ss"];
[dateFormatter setTimeZone:[NSTimeZone timeZoneWithName:#"asia/kolkata"]];
NSDate *date = [dateFormatter dateFromString:str];
In console : date-->2012-05-25 04:55:00 +0000....it lags behind 5 hours and 30 minutes and assumes GMT timezone instead of Asia...Why it is so?

When you see an [NSDate description] printed in the console, it is always the corresponding time in GMT. If you use the same date formatter to convert the date back to a string, it should be in the specified time zone.
An [NSDate description] is what you see if you type
po date
or
po [date description]
or you use NSLog to send either one of these forms to the console.

if you are looking for India Timezone you should use:

Related

Converting calendar date to the correct date

I am working on an application that creates alerts with calendar. I can correctly set alarms on correct dates. For example, I set an alarm for 4th of May 2017 1 PM.
When, I try to get the calendar event it returns me some other date in UTC.
As you can see, it returns me 10 AM on same day with UTC. I am wondering how can I get the exact date when I try to get it from calendar.
You just need to convert UTC to your local timezone.
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"yyyy-MM-dd HH:mm:ss"];
[dateFormatter setTimeZone:[NSTimeZone timeZoneWithAbbreviation:#"UTC"]];
NSDate *date1 = [dateFormatter dateFromString:#"2017-05-04 10:00:00"];
// change to a readable time format and change to local time zone
[dateFormatter setDateFormat:#"MM/dd/yyyy hh:mm a"];
[dateFormatter setTimeZone:[NSTimeZone localTimeZone]];
NSString *strCurrentLocalTimezoneDate = [dateFormatter stringFromDate:date1];
Date always takes current time zone until we changed other.If we print the Date it might be showing different but actually it takes current.
// except this code you may have to set timeZone as well.
NSDateFormatter *format = [[NSDateFormatter alloc] init];
[format setDateFormat:#"MMM-dd-yyyy"];
NSDate *now = [[NSDate alloc] init];
NSString *dateString = [format stringFromDate:now];
NSLog(#"%#",dateString);

NSDateFormatter return Date in GMT specific timezone

I want to get the date and time in a specific time zone. I am getting most of the things right but just at the end when i get the date from NSString using NSDateFormatter method it returns me the date in the GMT specific time zone. The method [formatter stringFromDate:gmtDate]; return me the expected date and time. The problem happen when i get the date from the string i-e when i execute this method self.localTime = [formatter dateFromString:str];. self.localTime is a NSDate property in my class.
So when i print the str it gives me the date and time in that specific time zone which is represented as self.timeZoneID, which is also a property on my class
NSDate *gmtDate = [NSDate date];
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setTimeZone:[NSTimeZone timeZoneWithName:self.timeZoneID]];
[formatter setDateFormat:#"yyyy-MM-dd HH:mm:ss"];
NSString *str = [formatter stringFromDate:gmtDate];
NSLog(#"Date string : %#", str);
self.localTime = [formatter dateFromString:str];
Any idea that what could be the reason that i am getting the right string output but when i assign it to my property localTime it give me the time in GMT
Reason is that NSDate have a default time zone that is GMT for consideration and when a user wants to have time specific for some time zone then NSDateFormatter provides way to set specific time zone which you are using for gmtDate object and not for self.localTime(this is taking GMT ,default time zone).

Why does stringFromDate NSString still have GMT time even though I set timezone on the NSDateFormatter?

The output for the actual NSDate object (firstTime) is what I want it to be (the iOS device's time). The NSString object (secondTime) still seems to be showing the GMT time (which is 4 hours ahead of my local time, EST) even though I set the date formatter (df) to the localTimeZone. Why is it not working?
NSDateFormatter *df = [[NSDateFormatter alloc] init];
[df setDateFormat:#"HH:mm:ss"];
[df setTimeZone:[NSTimeZone localTimeZone]];
NSDate *firstTime = [NSDate dateWithTimeInterval:[[NSTimeZone localTimeZone] secondsFromGMT] sinceDate:[NSDate date]];
NSLog(#"%#", firstTime);
NSString *secondTime = [df stringFromDate:firstTime];
NSLog(#"%#", secondTime);
Output:
FIRST TIME: 2014-05-07 17:41:29 +0000, SECOND TIME: 13:41:29
One should let NSDate capture the real date/time, without trying to perform any timezone adjustment, and then let the NSDateFormatter format the string so that it's represented in the desired timezone.
So, looking at your code:
NSDateFormatter *df = [[NSDateFormatter alloc] init];
[df setDateFormat:#"HH:mm:ss"];
[df setTimeZone:[NSTimeZone localTimeZone]];
That's fine, though the setting of the timezone to the local timezone is unnecessary. Date formatters default to the current timezone.
But then you proceed to attempt to grab the current time, and adjust it:
NSDate *firstTime = [NSDate dateWithTimeInterval:[[NSTimeZone localTimeZone] secondsFromGMT] sinceDate:[NSDate date]];
NSLog(#"%#", firstTime);
While I understand why you attempted to do that, this is incorrect. No adjustment for timezone should be performed. So, that assignment of firstTime should be:
NSDate *firstTime = [NSDate date];
NSLog(#"%#", firstTime);
So, if you did this at 5:41pm (eastern), this NSLog will now report 2014-05-07 21:41:29 +0000, but that's correct (because the +0000 indicates that it's showing you the time in UTC/GMT/Zulu).
Then, if you want to display that in the local timezone, you can take this un-adjusted [NSDate date] and use it with your formatter, like you did in your question:
NSString *secondTime = [df stringFromDate:firstTime];
NSLog(#"%#", secondTime);
That will then report 17:41:29, like you expected it to.
An NSDate does not have a time zone. Read that five times until you understand it.
This:
[NSDate date]
Returns the date that means now. It does not have a time zone. It is not in GMT or in any other time zone. It does not have one. Your code:
[NSDate dateWithTimeInterval:[[NSTimeZone localTimeZone] secondsFromGMT] sinceDate:[NSDate date]];
Means a time that isn't now for any user outside GMT. I'll repeat that: your NSDate doesn't describe now. It's like sitting in San Francisco, looking at your watch which is set in the correct local time and it saying 12:00 then telling everybody "that means it is 4AM because we're 8 hours behind GMT".
As a result:
[df stringFromDate:firstTime]
Will build a string that will show a time that isn't now.
Stop thinking you're smarter than everybody that's ever worked at Apple and try this:
NSDateFormatter *df = [[NSDateFormatter alloc] init];
[df setDateFormat:#"HH:mm:ss"];
[df setTimeZone:[NSTimeZone localTimeZone]];
NSString *secondTime = [df stringFromDate:[NSDate date]];
NSLog(#"%#", secondTime);
So that says "give me a string of 'now' in the local time zone". Tell me: does it output the correct thing?

Problems converting a string date to NSDate

I have this string date:
2014-04-21T07:55:13Z
when I convert that to NSDate I have the hour like 6:55... 1 hours less. WHY?
This is the code I am using to convert:
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"yyyy-MM-dd'T'HH:mm:ss'Z'"];
NSDate *newDate = [dateFormatter dateFromString:dateStr];
newDate is now 2014-04-21 06:55:13 +0000 !!!???
what is wrong?
NOTE: That one hour less would make sense if the date was my local time (GMT+1) being converted to GMT. But if that Z is zero offset ( = GMT) the date is already GMT.
I don't think your code is wrong. using this code:-
NSString *dateStr = #"2014-04-21T07:55:13Z";
// Convert string to date object
NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
[dateFormat setDateFormat:#"yyyy-MM-dd'T'HH:mm:ss'Z'"];
NSDate *date = [dateFormat dateFromString:dateStr];
NSLog(#" date log %#",date); //2014-04-21 02:25:13 +0000 output
// Convert date object to desired output format
[dateFormat setDateFormat:#"yyyy-MM-dd'T'HH:mm:ss'Z'"];
dateStr = [dateFormat stringFromDate:date];
NSLog(#"string %#",dateStr); //2014-04-21T07:55:13Z output
but NSLog of NSDATE is not output correct according to this NSDate Format outputting wrong date so your code is right.
The NSDate doesn't know anything about formatting (just date information), and the NSDateFormatter doesnt really know anything about dates, just how to format them. So you have to use methods like -stringFromDate: for know that is current or not to actually format the date for pretty human-readable display.
NSLog(#" date is %#",[dateFormat stringFromDate:date]);

Creating NSDate object with specific time zone

I've written a method that accepts a NSDate object and should turn it into a NSDate object with EST time zone. The way I've seen other people accomplish this is by using a date formatter to change the date to a string with the specified time zone. The issue is when I try to change that string back to a NSDate object using "dateFromString".
- (NSDate*)turnToEST:(NSDate*)date
{
NSLog(#"turnToEST called with date %#", date);
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc]init];
[dateFormatter setDateFormat:#"yyyy-MM-dd HH:mm:ss"];
[dateFormatter setTimeZone:[NSTimeZone timeZoneWithAbbreviation:#"EST"]];
NSString *stringFromDate = [dateFormatter stringFromDate:date];
NSLog(#"date formatted is %#", stringFromDate);
NSDate *dateFromString = [[NSDate alloc] init];
NSDateFormatter *dateFormatter2 = [[NSDateFormatter alloc]init];
[dateFormatter2 setDateFormat:#"yyyy-MM-dd HH:mm:ss"];
dateFromString = [dateFormatter2 dateFromString:stringFromDate];
NSLog(#"date has been changed to %#", dateFromString);
return date;
}
With output...
turnToEST called with date 2013-12-19 14:15:17 +0000
date formatted is 2013-12-19 09:15:17
date has been changed to 2013-12-19 14:15:17 +0000
I'm not sure why this is any different than
Converting NSString to NSDate (and back again)
NSDate values do not have an associated time zone, they represent an abstract moment in time. So "a NSDate object with EST time zone" isn't a thing that exists. Time zones only come into play when formatting them for output, or trying to do calendar-based math.
NSLog always uses UTC when printing its output.
So you're taking a moment in time, formatting it to a string in a particular time zone, and then parsing it back into the same moment in time. That's working as intended.

Resources