views:

60

answers:

2

I have some methods that return the number of weekdays between two given dates. Since calling these methods become very expensive to call when the two dates lie years apart, I'm wondering how these methods could be refactored in a more efficient way. The returned result is correct but I feel that the iphone processor is struggling to keep up and consequently freezes up the application when I would call these methods over a period of say 10years. Any suggestions ?

    //daysList contains all weekdays that need to be found between the two dates
    -(NSInteger) numberOfWeekdaysFromDaysList:(NSMutableArray*) daysList 
                                              startingFromDate:(NSDate*)startDate 
                                              toDate:(NSDate*)endDate
    {
     NSInteger retNumdays = 0;

     for (Day *dayObject in [daysList objectEnumerator])
     {
      if ([dayObject isChecked])
      {
       retNumdays += [self numberOfWeekday:[dayObject weekdayNr] startingFromDate:startDate toDate:endDate];
      }
     }

     return retNumdays;
    }


    -(NSInteger) numberOfWeekday:(NSInteger)day 
                                 startingFromDate:(NSDate*)startDate 
                                 toDate:(NSDate*)endDate
    {
     NSInteger numWeekdays = 0;
     NSDate *nextDate = startDate;

     NSComparisonResult result = [endDate compare:nextDate];

     //Do while nextDate is in the past
     while (result == NSOrderedDescending || result == NSOrderedSame) 
     {
      if ([NSDate weekdayFromDate:nextDate] == day)
      {
       numWeekdays++; 
      }

      nextDate = [nextDate dateByAddingDays:1];
      result = [endDate compare:nextDate];
     }

     return numWeekdays;
    }
A: 

You need to create an formula to calculate the number of weekdays rather than loop thru each day and count them.

Something like this (this is a rough approximation), where startJD and endJD are the Julian Dates:

nWeekdays = (endJD - startJD) * 5 / 7;  

Of course that's close but not exact since it doesn't take into account what day of the week it starts and ends on. But that's the general idea, you need a formula, not a loop.

You can also find quite a bit on this topic by searching.

progrmr
A: 

Why not look at the core foundation classes that handle dates?

CFAbsoluteTimeGetDayOfWeek Returns an integer representing the day of the week indicated by the specified absolute time.

SInt32 CFAbsoluteTimeGetDayOfWeek ( CFAbsoluteTime at, CFTimeZoneRef tz );

Parameters at : The absolute time to convert. tz : The time zone to use for time correction. Pass NULL for GMT.

Return Value : An integer (1-7) representing the day of the week specified by at. Per ISO-8601, Monday is represented by 1, Tuesday by 2, and so on.

Availability Available in iOS 2.0 and later. Declared In CFDate.h

More can be found at: http://developer.apple.com/library/ios/#documentation/CoreFoundation/Conceptual/CFDatesAndTimes/

Chip Coons