There are plenty of code snippets and tutorials online about how to convert a NSString to a NSDate. Unfortunately for me I could not just plug them into the iPhone app that I am writing.
Here’s what you typically see:
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; [dateFormatter setDateFormat:@"MM-dd-yyyy hh:mm aaa"]; NSDate *aDate = [dateFormatter dateFromString:(NSString *)dateString];
This will create a NSDate object named aDate. The only problem is that aDate will have the timezone of GMT. It also assumes that the string passed in has an implied timezone of GMT. I don’t have any problem with dates that have a timezone of GMT. That’s how I store all the dates in the database. When I later use NSDateFormatter stringFromDate it will convert the time component of the date to the system timezone (or local timezone if you change the timezone programmatically for the app). So I get time conversion for “free” without having to worry about the timezone the device is currently in or daylight savings time. Those are headaches I can do without!
My specific problem is that the string that I am converting to a date is based on local time for a different timezone than where I am at. I am in Eastern/New York. Some of the strings are Central, some are Mountain. Since I am only dealing with two locations, I can hard-code the timezone based on another string that gives me the location name.
Here is what I am doing:
// Convert the date from another timezone to GMT time
- (NSDate *)MakeDateFromString:(NSString *)aDate forLocation:(NSString *)location withFormat:(NSString *)format{
NSString *beginLocation = [location substringToIndex:1];
NSString *timeZoneAbbr;
if ([beginLocation isEqualToString:@"D"]) {
timeZoneAbbr = @"MST";
}
else {
timeZoneAbbr = @"CST";
}
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:format];
NSDate *firstDate = [dateFformatter dateFromString:(NSString *)aDate];
//firstDate is now converted to GMT time based on the timezone
// the device is located in. We do this by finding the difference
// between the timezone the string comes from and the local timezone.
NSTimeZone* sourceTimeZone = [NSTimeZone timeZoneWithAbbreviation:timeZoneAbbr];
NSTimeZone* destinationTimeZone = [NSTimeZone systemTimeZone];
NSInteger sourceGMTOffset = [sourceTimeZone secondsFromGMTForDate:firstDate];
NSInteger destinationGMTOffset = [destinationTimeZone secondsFromGMTForDate:firstDate];
NSTimeInterval interval = destinationGMTOffset - sourceGMTOffset;
NSDate* destinationDate = [[NSDate alloc] initWithTimeInterval:interval sinceDate:firstDate];
// destinationDate is now GMT time, with the correction made
// between the origination timezone and the local timezone.
return destinationDate;
This is how it works:
1. First, I determine the timezone of the local time passed to me. As I said, I only have two locations and can determine that by the first letter of the location.
2. Next I convert the string date passed in to be a date. This will be converted to GMT time, but if the time component of the string is not the same timezone as you are located it will be off by the difference in timezones.
3. Next I create two timezones, sourceTimeZone and destinationTimeZone. sourceTimeZone is for the time zone of the location. destinationTimeZone is for the system timezone.
4. I get the offset in seconds for each timezone from GMT.
5. I then create an interval for the difference between the timezone offsets.
6. That interval is used to adjust the original date created from the string.