0

I've got two dates that are set with a button press. These are stored in a custom object that inherits from NSObject.

Properties:

@property (nonatomic, strong) NSDate *firstDate;
@property (nonatomic, strong) NSDate *secondDate;

Custom getter and setter methods:

- (void)setFirstDate:(float)firstDate {
    _firstDate = [self dateByOmittingSeconds:firstDate];
}

- (void)setSecondDate:(float)secondDate {
    _secondDate = [self dateByOmittingSeconds:secondDate];
}

- (NSDate *)firstDate {
    return [self dateByOmittingSeconds:_firstDate];
}

- (NSDate *)secondDate {
    return [self dateByOmittingSeconds:_secondDate];
}

Function that removes the seconds part of the NSDate:

-(NSDate *)dateByOmittingSeconds:(NSDate *)date
{
// Setup an NSCalendar
NSCalendar *gregorianCalendar = [[NSCalendar alloc] initWithCalendarIdentifier: NSCalendarIdentifierGregorian];

// Setup NSDateComponents
NSDateComponents *components = [gregorianCalendar components: NSUIntegerMax fromDate: date];

// Set the seconds
[components setSecond:00];

return [gregorianCalendar dateFromComponents: components];
}

firstDate is 08:00 and secondDate is 13:00, both are set today.

I'm getting the distance between the two dates and format them like this:

NSString *myString = [self timeFormatted:[currentModel.secondDate timeIntervalSinceDate:currentModel.firstDate]];


- (NSString *)timeFormatted:(int)totalSeconds
{

// int seconds = totalSeconds % 60;
int minutes = (totalSeconds / 60) % 60;
int hours = totalSeconds / 3600;

return [NSString stringWithFormat:@"%luh %lum", (unsigned long)hours, (unsigned long)minutes];
}

But it reports 4h 59m, 17999.254732 seconds.

Does anyone have a clue on why this is?

Thanks!

Erik
  • 2,500
  • 6
  • 28
  • 49

1 Answers1

1

The problem is not timeIntervalSinceDate but your dateByOmittingSeconds method which does not correctly truncate to seconds. The reason is that second is not the smallest unit in NSDateComponents. There is also nanosecond and if you set that one to zero as well

[components setSecond:0];
[components setNanosecond:0];

then it will work as expected.

A slightly easier solution is to use rangeOfUnit:

-(NSDate *)dateByOmittingSeconds:(NSDate *)date
{
    NSCalendar *gregorianCalendar = [[NSCalendar alloc] initWithCalendarIdentifier: NSCalendarIdentifierGregorian];
    NSDate *result;
    [gregorianCalendar rangeOfUnit:NSCalendarUnitSecond startDate:&result interval:nil forDate:date];
    return result;
}
Martin R
  • 529,903
  • 94
  • 1,240
  • 1,382
  • I came up with that idea myself that there might have been a smaller unit and tried to find like setMillisecond or similar but I couldn't find it. Nanosecond is the unit I was looking for - works perfectly now, thanks a lot! – Erik May 15 '15 at 18:28