Matts
Matts

Reputation: 53

NSDate incorrect timezone interpretation

When I have a time-string with value "17:00:00 +0000", it is converted to 18:00:00 CET by the dateformatter. But I want to have 17:00:00 in the NSDate.

This is the code I use in a certain method to return a NSDate a object

NSString* time = @"17:00:00 +0000";
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];

[dateFormatter setTimeZone:[NSTimeZone timeZoneWithAbbreviation:@"GMT"]];
[dateFormatter setDateFormat:@"HH:mm:ss Z"];

NSDate* convertedDate = [dateFormatter dateFromString:time];

This is the part where I need the hour as an integer

NSDateComponents *components = [calendar components:(NSHourCalendarUnit | NSMinuteCalendarUnit) fromDate:time];
[components setTimeZone:[NSTimeZone timeZoneWithAbbreviation:@"GMT"]];
NSInteger hour = [components hour];

Hour will be 18 instead of 17.

Upvotes: 1

Views: 598

Answers (1)

MANIAK_dobrii
MANIAK_dobrii

Reputation: 6032

The problem is with the code where you use your date and not where you convert string to date. You could try to set calendar's time zone instead of NSDateComponents's to get desired behaviour:

[calendar setTimeZone:[NSTimeZone timeZoneWithName:@"GMT"]];
// and then do the rest
NSDateComponents *components = [calendar components:(NSHourCalendarUnit | NSMinuteCalendarUnit) fromDate:time];
NSInteger hour = [components hour];

NSDate does not store any custom time zone (it stores all the data in the same "base" time zone), you can display NSDate instance converted to specified time zone, but can't set any time zone for any NSDate instance. So, time zones jumps in only when you display it to the user. Also, the rule of thumb says: always store/transmit data in UTC.

NSDate *date = ...
date.timeZone = ... // No such thing
// this is how you can see which time is represented by NSDate in a specific time zone
// note there's no such function as StringFromNSDateWithTimeZone
NSLog("TimeZone: %@", StringFromNSDateWithTimeZone(date, SOME_TIME_ZONE)) 

That means that you should check your NSDate display code but not your string to NSDate code (it seems to do what you'd expect).

Just to add more glue: 17:00:00 +0000 (GMT) = 18:00:00 +0100 (CET)

Upvotes: 0

Related Questions