I know that this is because [the NSDateFormatter
] converts the NSString
with respect to GMT…
No, you're wrong. NSDateFormatter
defaults to using your current time zone.
What you're not understanding is that "2015-06-02 18:19:37 +0000" is the same date and time as "2015-06-03 02:19:37" (in your local time zone, which must be GMT+0800).
Also, the description that you logged is just one representation of the date. The date does not have a year, month, day-of-month, hour, minute, second, or any of that. A date object just represents a moment in time. Such moments don't have any of that and neither do NSDate
objects. Only representations of moments have those things, and they are only arrived at by processing the date through a specific calendar and time zone. In any case, any given date has multiple representations. Just because the description that gets logged happens to choose a representation that you weren't expecting doesn't mean the date is wrong.
You have implicitly requested a conversion from an NSDate
object to a string when you logged it. That's because logging always involves strings. The string-formatting code used by NSLog()
and the %@
format specifier uses the -description
method. You are never going to be able to force NSDate
's implementation of -description
to use your time zone, so don't try.
If you really need a string representation (and you're not just debugging) and you want it in some specific time zone or otherwise want to dictate the format, don't rely on the -description
method like you are. Instead, use a date formatter to convert from NSDate
to an NSString
explicitly, and configure the date formatter to produce the representation that you want.
But don't confuse the need to do that with the date being wrong.
What I really wanted to do is to check if the given NSDate
is already past 9PM EST (-4GMT), while i'm on +8GMT timezone.
So, use NSCalendar
, NSTimeZone
, and NSDateComponents
to construct an NSDate
for 9PM EST (on the current day, I suppose you mean) and then compare the dates.
NSDate* date = /* ... */;
NSCalendar* calendar = [[NSCalendar alloc] initWithIdentifier:NSCalendarIdentifierGregorian];
calendar.timeZone = [NSTimeZone timeZoneWithName:@"America/New_York"];
NSDate* deadline = [calendar dateBySettingHour:21 minute:0 second:0 ofDate:date options:0];
if ([date compare:deadline] == NSOrderedDescending)
/* date is after deadline */;
Here I used the convenience method -dateBySettingHour:minute:second:ofDate:options:
and avoided direct use of NSDateComponents
. If your needs differ, you might have to convert the date to date components using the calender, modify the components, convert them back to a date, and then compare.