4

I have difficulties with the following task: I have a NSMutableArray containing NSManagedObjects "OpeningHours" which I pull from core data.

NSMutableArray *openingHoursArray = [NSMutableArray arrayWithArray: [[museum valueForKey:@"openingHours"] allObjects]];

The array is unsorted, as getting the value for keys from my NSManagedObject "museum" returns a randomly organized set.

The NSManagedObjects "openingHours" in the array have values of type NSDate, accessible via the keys "start" and "end". Now, to display my Opening Hours in a way that makes sense, I access the weekday and time information of the respective dates, that works fine so far using this piece of code:

NSLocale *locale = [[NSLocale alloc] initWithLocaleIdentifier:mainDelegate.localeCode];

NSDateFormatter *weekday = [[[NSDateFormatter alloc] init] autorelease];
[weekday setLocale:locale];
[weekday setDateFormat: @"EEEE"];

[NSDateFormatter *time = [[[NSDateFormatter alloc] init] autorelease];
[time setLocale:locale];
[time setTimeStyle:NSDateFormatterShortStyle];

for (NSManagedObject *openingHour in openingHoursArray) {

        NSLog(@"%@", [openingHour valueForKey:@"start"]);
        NSDate *startDate = [openingHour valueForKey:@"start"];
        NSDate *endDate = [openingHour valueForKey:@"end"];


        NSString *startDay = [weekday stringFromDate:startDate];
        NSString *endDay = [weekday stringFromDate:endDate];
        NSString *startTime = [time stringFromDate:startDate];
        NSString *endTime = [time stringFromDate:endDate];


        if (![startDay isEqualToString:endDay]) {
            [openingHoursString appendFormat:@"%@ - %@:\t%@ - %@ \n", startDay, endDay, startTime, endTime];         
        }
        else {
            [openingHoursString appendFormat:@"%@:\t%@ - %@ \n", startDay, startTime, endTime];             
        }

    }

This gives me the desired output:

Thursday: 10:00 AM - 9:00 PM

Friday - Sunday: 10:00 AM - 6:00 PM

Monday - Wednesday: 10:00 AM - 5:00 PM

Now the problem is: of course I want the Monday opening period to be displayed first. I need to sort my array by the weekday of the start date value. I tried sorting it using the following:

NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"start" ascending:TRUE];
[openingHoursArray sortUsingDescriptors:[NSArray arrayWithObject:sortDescriptor]];

but obviously this doesn't work because it simply sorts by dates, and 1970-01-01 was unfortunately a thursday, therefore thursday will be the first item of my array sorted by above code.

Does anyone have a good idea on how to "sort this out"? :-) I'm completely stuck with this.. Thanks a lot!

Julia
  • 65
  • 5
  • It might be better to just shift your start date by 2 days instead of implementing date sorting, or do you have additional reasoning for wanting date prioritizing? – Karoly S Aug 19 '11 at 14:57
  • that's an idea, but i cannot know by how many days i would have to shift, as the opening hours may vary - there might be an individual opening hour for every day, or cover longer periods like "mon - sat", or basically anything else.. i need a solution that will work for any combination of opening hours, always displaying monday first (if monday is an open day).. kinda tricky i guess! – Julia Aug 19 '11 at 15:07

2 Answers2

3

Something like this should work:

NSCalendar *calendar = [[[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar] autorelease];
NSArray *sortedArray = [openingHoursArray sortedArrayUsingComparator: ^(id obj1, id obj2) {
    NSDate *startDate1 = [obj1 valueForKey:@"start"];
    NSDate *startDate2 = [obj2 valueForKey:@"start"];
    NSDateComponents *components1 = [calendar components:NSWeekdayCalendarUnit fromDate:startDate1];
    NSDateComponents *components2 = [calendar components:NSWeekdayCalendarUnit fromDate:startDate2];
    NSInteger weekday1 = [components1 weekday];
    if (weekday1 == 1) weekday1 = 8; //Order sundays last
    NSInteger weekday2 = [components2 weekday];
    if (weekday2 == 1) weekday2 = 8;
    return [[NSNumber numberWithInteger:weekday1] compare:[NSNumber numberWithInteger:weekday2]];
}];
omz
  • 53,243
  • 5
  • 129
  • 141
-1

Instead of using a NSSortDescriptor, use NSArray's sortedArrayUsingSelector or NSMutableArray's sortUsingSelector methods, and pass in @selector(compare:) as the selector.

See this answer for more info: Click

Community
  • 1
  • 1
thomashw
  • 956
  • 4
  • 7