I'm somewhat confused about how these two NSDate objects seem to know which timezone they are in. I was under the impression that an NSDate object only stored a point in time and no information about the timezone.
I'm creating and logging two dates like this:
NSString* timeString = #"6:04 PM";
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setLocale:[NSLocale localeWithLocaleIdentifier:#"en_US_POSIX"]];
[dateFormatter setDateFormat:#"h:mm a"];
NSDate *time = [dateFormatter dateFromString:timeString];
NSDateFormatter *currentFormatter = [[NSDateFormatter alloc] init];
[currentFormatter setTimeStyle:NSDateFormatterLongStyle];
NSLog(#"%#", [currentFormatter stringFromDate:time]);
NSLog(#"%#", [currentFormatter stringFromDate:[NSDate date]]);
This produces the output:
18:04:00 GMT
11:12:36 BST
How does it know that the first date is GMT and the second is BST?
(It's British Summer Time here. Your mileage may vary in that respect)
You're right, NSDate doesn't have a time zone. Your results don't contradict that, because you're not printing the dates-- you're printing a subset of the date information produced by passing them through a date formatter. Your currentFormatter only returns time of day information, not date information. If you add this line:
[currentFormatter setDateStyle:NSDateFormatterLongStyle];
Then the results will look something like:
January 1, 2000 at 6:04:00 PM MST
September 30, 2015 at 11:14:39 AM MDT
In other words, they show up with different time zones because they're on different dates, and the time zone reflects what's in effect on that date. In my case it's currently MDT but on Jan 1 2000 it would have been MST.
Related
I'm converting 12 hour date to 24 here, but it failed to get perfect time.
Here is code :
NSString *dateStr = #"2016-08-12T04:10:14.915Z";
NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
[dateFormat setDateFormat:#"yyyy-MM-dd'T'hh:mm:ss.SSS'Z'"];
[dateFormat setTimeZone:[NSTimeZone localTimeZone]];
NSDate *date = [dateFormat dateFromString:dateStr];
and my final date is
2016-08-11 22:40:14 +0000
How ?
The NSDate object that you are getting is GMT. In France GMT -2, if I run your code I have a time of 02:10.
Am I correct assuming your GMT offset is -5:30 ?
NSDate objects don't have time zones; they represent an absolute
moment in time. However, when you ask one for its description (by
printing it in an NSLog, e.g.), it has to pick a time zone. The most
reasonable "default" choice is GMT. If you're not in GMT yourself, the
date will seem to be incorrect, by the amount of your own offset.
You should always use an NSDateFormatter, setting its timezone to
yours, before displaying a date.
Don't trust what NSLog or the debbuger are telling you about a NSDate.
use
NSString dateAsString = [dateFormat stringFromDate:date];
to check your date :)
trying to convert NSString to NSDate
NSString *startDateForCal='09-03-2016 08:00:00 AM'
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat: #"dd-MM-yyyy HH:mm:ss a"];
NSDate * EventStart = [dateFormatter dateFromString: startDateForCal];
But getting mixed result as "2016-03-09 18:30:00 +0000" returning date as correct but time didn't match with string It would be welcome any suggestions
Thank you
it should be
[dateFormatter setDateFormat: #"dd-MM-yyyy hh:mm:ss a"];
i.e. no capital HH for hour. HH return the Hour in 24 format
For more details Click now
and regarding the error in date,
since you have set the time format wrong( as HH instead of hh), it took the time as 12:00 AM and showed it in GMT timezone(IST - 5 and half hours, so in your case 12:00 AM - 5:30 = 18:30 of previous day), i guess you haven't set the locale properly.
setting the locale(in swift),
dateFormatter.locale = NSLocale(localeIdentifier:"en_IN")
Your question makes no sense. Your goal was to obtain an NSDate from an NSString. You did that, and you did it successfully.
How you discover what that NSDate is, is a completely different matter. It is represented to you by default (in the console) in a certain time zone and format. But that is irrelevant; it is still the same date, and it is the correct date.
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?
Here's the code:
NSDateFormatter* dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setTimeZone:[NSTimeZone timeZoneWithAbbreviation:#"UTC"]];
[dateFormatter setDateFormat:#"yyyy-MM-dd'T'HH:mm:ss'Z'"];
NSDate* newTime = [dateFormatter dateFromString:#"2011-10-19T12:22:07Z"];
[dateFormatter setTimeZone:[NSTimeZone systemTimeZone]];
[dateFormatter setDateFormat:#"dd-MMM-yyyy HHmm"];
NSString* finalTime = [dateFormatter stringFromDate:newTime];
The problem:
I'm in Toronto (EST, GMT-5). My final time SHOULD show 0722, I'm seeing 0822. Inspecting the objects I can see that newTime is '2011-10-19 08:22:07 EDT'. I'm not sure why that happens but it persists onto the finalTime string despite setting the dateFormatter time zone to systemTimeZone. I assume systemTimeZone is EDT then? Any insight into why this happens or how I can correct it would be greatly appreciated.
Thanks in advance.
You're currently in Toronto EST. This time report you are getting back is showing EDT. Which is Eastern Daylight Time. Make sure you subtract an hour for daylight savings time since it's EDT not EST.
I'm out right now so I can't test this code but I think this should work:
NSDate *currentDate = [NSDate date];
NSTimeZone *currentZone = [NSTimeZone localTimeZone];
if ([currentZone isDaylightSavingTimeForDate:currentDate]) {
//adjust the time by 1 hour here
}
A few things:
Don't set the timezone on the date formatter. And then remove the quotes around the Z in the format string. This will allow the date formatter to determine the timezone from the actual date string.
The output of 0822 is correct for your system timezone because you were on day light savings time on October 19th. On that date you were GMT-4, not GMT-5. In Canada, in 2011, DST ended on November 6th.
The following code in iOS
NSDateFormatter *formatter = [[[NSDateFormatter alloc] init] autorelease];
[formatter setDateStyle:NSDateFormatterFullStyle];
[formatter setTimeStyle:NSDateFormatterLongStyle];
[formatter setTimeZone:[NSTimeZone timeZoneWithAbbreviation: #"UTC"]];
NSString *dateString = [formatter stringFromDate: date];
returns a date string like
Monday, May 6, 2013, 10:42:10 PM GMT
Unfortunately, UTC is not exactly the same at GMT--it's off by one hour when the UK is on daylight savings time. How to I convince NSDateFormatter to actually return UTC rather than GMT?
According to this post, the two are implemented the same in code. I don't believe you need to worry about it.