2
votes

Using NSDate is tricky to me. I know it represents a specific point in time, not tied to a specific time zone or locale. I've also read a lot fo the docs on NSDateFormatter, NSCalendar, NSDateComponents, NSlocale, and NSTimeZone.

I'm trying to do calculations based on two specific Pacific time zones. For example, I want to be able to count the number of days from date A to date B. I don't want to 'hack' it by parsing strings, as I want things like DST to be calculated as well.

Can anyone recommend a way to do this?

Edit: Found solution:

NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSTimeZone *zone = [NSTimeZone timeZoneWithName:@"PST"];
[calendar setTimeZone:zone];
NSDateComponents *comp = [calendar components:(NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit) fromDate:date];
date = [calendar dateFromComponents:comp];
[calendar release];

This results in a date localized to Pacific time. I know this causes problems with different locales, but my app is unique, and this is justified.

I can then compare dates using the division by 86400 as was posted.

Although, it seems like overkill - a lot of extra work - perhaps there is a shorter way to get a date with a specific time zone?

3

3 Answers

2
votes

You should create two NSDate instances that represent the two dates you want to compare. To do this, you can set up NSDateComponents instances and set not only their day/month/year/hour but also their time zone (-[NSDateComponents setTimeZone:]). Then call -[NSDateComponents date] to convert them to NSDate.

[date1 timeIntervalSinceDate:date2] then gives the difference (in seconds) between the two dates. Divide the result by 86,400 to get the number of days.

Alternatively, you can call [NSCalendar components:fromDate:toDate:options:] with the NSDateComponent instances directly to get an NSDateComponents with the difference between the two.

4
votes

You could also convert both NSDate objects to GMT. Like this:

NSDate *date;
NSTimeZone *timeZone;
NSDate *gmtDate = [date dateByAddingTimeInterval:-[timeZone secondsFromGMTForDate:date]];

And then set the NSCalendar's time zone to GMT. Like this:

NSCalendar *calendar;
[calendar setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0];

You can then use the calendar and your GMT dates to calculate whatever you need to know.

3
votes

I suppose you could calculate the difference between the time zones. Like this:

NSDate *date1;
NSDate *date2;
NSTimeInterval dateDifference = [date1 timeIntervalSinceDate:date2];

Then calculate the time zone difference. Like this:

NSTimeZone *timeZone1;
NSTimeZone *timeZone2;
// Assuming date1 is in timeZone1...
NSTimeInterval timeZoneDifference = [timeZone1 secondsFromGMTForDate:date1] - [timeZone2 secondsFromGMTForDate:date2];

Then sum the two. Like this:

NSTimeInterval difference = dateDifference + timeZoneDifference;