排序数组只使用时间?

时间:2022-01-24 19:42:42

I'm currently sorting an array of objects with a property startTime however I have realised that it is sorting by day and time.

我目前正在用属性startTime对对象数组进行排序,但是我已经意识到它是按天和时间排序的。

So if I add an object and set the time to something earlier than a pre made one, if its made more than a day later it will always be listed after the other. Make sense?

因此,如果我添加一个对象,并将时间设置为比pre - made更早的时间,如果它的制作时间超过一天,它将总是在另一个对象之后被列出。有意义吗?

So lets say my NSDate is Tuesday 25th 6:02PM. I want to scratch the Tuesday 26th bit and only sort by time, the day doesn't matter to me. How can I do this?

所以我们说,我的NSDate是星期二25点06分。我想把星期二的第26位划掉,只按时间排序,这一天对我来说无所谓。我该怎么做呢?

Thanks.

谢谢。

P.S This is how I am currently sorting my objects:

P。这就是我目前对对象排序的方式:

NSSet *tasks = [self.routine task];
    NSSortDescriptor *sort = [[NSSortDescriptor alloc] initWithKey:@"startTime" ascending:YES];
    NSArray *sorted = [[tasks allObjects] sortedArrayUsingDescriptors:[NSArray arrayWithObject:sort]];

2 个解决方案

#1


7  

Create a category on NSDate that returns the time interval since the start of the day for the current calendar and time zone, and then use that time interval to do your sorting.

在NSDate上创建一个类别,该类别返回当前日历和时区的开始时间间隔,然后使用该时间间隔进行排序。

@interface NSDate (CBVAdditions)

- (NSTimeInterval)cbvTimeIntervalSinceStartOfDay;

@end

@implementation NSDate (CBVAdditions)

- (NSTimeInterval)cbvTimeIntervalSinceStartOfDay
{
    NSCalendar *calendar = [NSCalendar currentCalendar];
    NSTimeZone *timeZone = [NSTimeZone defaultTimeZone];
    NSDateComponents *dateComponents = [calendar components:(NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit) fromDate:self];
    [dateComponents setCalendar:calendar];
    [dateComponents setTimeZone:timeZone];
    NSInteger hoursComponent = dateComponents.hour * 3600;
    NSInteger minutesComponent = dateComponents.minute * 60;
    double secondsComponent = dateComponents.second;
    NSTimeInterval toReturn = hoursComponent + minutesComponent + secondsComponent;
    return toReturn;
}

@end

Then, you can use NSSortDescriptor with a key like @"dateProperty.cbvTimeIntervalSinceStartOfDay" to do the actual sorting. For example, I show the Event class, and some code that accomplishes the sort.

然后,您可以使用NSSortDescriptor与一个类似@"dateProperty的键。cbvTimeIntervalSinceStartOfDay来做实际的排序。例如,我展示了事件类,以及一些完成排序的代码。

@interface Event : NSObject

@property (nonatomic, strong) NSString *name;
@property (nonatomic, strong) NSDate *eventDate;

@end

@implementation Event

- (NSString *)description
{
    NSString *desc = [NSString stringWithFormat:@"%@, name = %@, eventDate = %@",[super description], self.name, [self.eventDate descriptionWithLocale:[NSLocale currentLocale]]];
    return desc;
}
@end

...

Event *e1 = [Event new];
e1.eventDate = [NSDate date];
e1.name = @"e1";
Event *e2 = [Event new];
e2.eventDate = [NSDate dateWithTimeIntervalSinceNow:(-1 * 22 * 3600)];
e2.name = @"e2";
Event *e3 = [Event new];
e3.eventDate = [NSDate dateWithTimeIntervalSinceNow:3600];
e3.name = @"e3";

NSArray *events = @[e1,e2,e3];
NSLog(@"Events = %@", events);
NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"eventDate.cbvTimeIntervalSinceStartOfDay" ascending:YES];
NSArray *sortedEvents = [events sortedArrayUsingDescriptors:@[sortDescriptor]];
NSLog(@"Sorted Events = %@", sortedEvents);

Executing this code presented the following output:

执行此代码时,输出如下:

2013-01-15 15:50:54.221 DateSortingFun[67319:c07] Events = (
    "<Event: 0x717b050>, name = e1, eventDate = Tuesday, January 15, 2013, 3:50:54 PM Mountain Standard Time",
    "<Event: 0x717b620>, name = e2, eventDate = Monday, January 14, 2013, 5:50:54 PM Mountain Standard Time",
    "<Event: 0x717b650>, name = e3, eventDate = Tuesday, January 15, 2013, 4:50:54 PM Mountain Standard Time" ) 


2013-01-15 15:50:54.222 DateSortingFun[67319:c07] Sorted Events = (
    "<Event: 0x717b050>, name = e1, eventDate = Tuesday, January 15, 2013, 3:50:54 PM Mountain Standard Time",
    "<Event: 0x717b650>, name = e3, eventDate = Tuesday, January 15, 2013, 4:50:54 PM Mountain Standard Time",
    "<Event: 0x717b620>, name = e2, eventDate = Monday, January 14, 2013, 5:50:54 PM Mountain Standard Time" )

#2


4  

use comparison blocks. and in the block create a new data with year, month and date set to the same day. that do a normal compare on those dates.

使用比较块。在块中创建新的数据,并将年、月和日期设置为同一天。在这些日期上做一个正常的比较。

    NSDateComponents *comps = [[NSDateComponents alloc] init];
    comps.year = 2007;
    comps.month = 12;
    comps.day = 3;
    comps.hour = 12;
    comps.minute = 3;

    NSDate *date1 = [[NSCalendar currentCalendar] dateFromComponents:comps];

    comps.year = 2012;
    comps.month = 9;
    comps.day = 7;
    comps.hour = 11;
    comps.minute = 13;

    NSDate *date2 = [[NSCalendar currentCalendar] dateFromComponents:comps];

    comps.year = 2021;
    comps.month = 12;
    comps.day = 3;
    comps.hour = 12;
    comps.minute = 5;

    NSDate *date3 = [[NSCalendar currentCalendar] dateFromComponents:comps];

    comps.year = 2021;
    comps.month = 12;
    comps.day = 3;
    comps.hour = 13;
    comps.minute = 5;


    NSDate *date4 = [[NSCalendar currentCalendar] dateFromComponents:comps];

    NSArray *dates = @[date1, date2, date3, date4];

    NSArray *oderedByTimeOnlyDates = [dates sortedArrayUsingComparator:^NSComparisonResult(NSDate *d1, NSDate *d2) {
        NSDateComponents *comps1 = [[NSCalendar currentCalendar] components:(NSHourCalendarUnit| NSMinuteCalendarUnit | NSSecondCalendarUnit)
                                                                  fromDate:d1];
        NSDateComponents *comps2 = [[NSCalendar currentCalendar] components:(NSHourCalendarUnit| NSMinuteCalendarUnit | NSSecondCalendarUnit)
                                                                   fromDate:d2];

        NSDate *date1 = [[NSCalendar currentCalendar] dateFromComponents:comps1];
        NSDate *date2 = [[NSCalendar currentCalendar] dateFromComponents:comps2];
        return [date1 compare:date2];
    }];

    NSLog(@"%@", oderedByTimeOnlyDates);

output:

输出:

(
    "2012-09-07 09:13:00 +0000",
    "2007-12-03 11:03:00 +0000",
    "2021-12-03 11:05:00 +0000",
    "2021-12-03 12:05:00 +0000"
)

The output is in UTC time, while they were created in UTC+1.

输出以UTC时间为单位,而它们是在UTC+1中创建的。

#1


7  

Create a category on NSDate that returns the time interval since the start of the day for the current calendar and time zone, and then use that time interval to do your sorting.

在NSDate上创建一个类别,该类别返回当前日历和时区的开始时间间隔,然后使用该时间间隔进行排序。

@interface NSDate (CBVAdditions)

- (NSTimeInterval)cbvTimeIntervalSinceStartOfDay;

@end

@implementation NSDate (CBVAdditions)

- (NSTimeInterval)cbvTimeIntervalSinceStartOfDay
{
    NSCalendar *calendar = [NSCalendar currentCalendar];
    NSTimeZone *timeZone = [NSTimeZone defaultTimeZone];
    NSDateComponents *dateComponents = [calendar components:(NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit) fromDate:self];
    [dateComponents setCalendar:calendar];
    [dateComponents setTimeZone:timeZone];
    NSInteger hoursComponent = dateComponents.hour * 3600;
    NSInteger minutesComponent = dateComponents.minute * 60;
    double secondsComponent = dateComponents.second;
    NSTimeInterval toReturn = hoursComponent + minutesComponent + secondsComponent;
    return toReturn;
}

@end

Then, you can use NSSortDescriptor with a key like @"dateProperty.cbvTimeIntervalSinceStartOfDay" to do the actual sorting. For example, I show the Event class, and some code that accomplishes the sort.

然后,您可以使用NSSortDescriptor与一个类似@"dateProperty的键。cbvTimeIntervalSinceStartOfDay来做实际的排序。例如,我展示了事件类,以及一些完成排序的代码。

@interface Event : NSObject

@property (nonatomic, strong) NSString *name;
@property (nonatomic, strong) NSDate *eventDate;

@end

@implementation Event

- (NSString *)description
{
    NSString *desc = [NSString stringWithFormat:@"%@, name = %@, eventDate = %@",[super description], self.name, [self.eventDate descriptionWithLocale:[NSLocale currentLocale]]];
    return desc;
}
@end

...

Event *e1 = [Event new];
e1.eventDate = [NSDate date];
e1.name = @"e1";
Event *e2 = [Event new];
e2.eventDate = [NSDate dateWithTimeIntervalSinceNow:(-1 * 22 * 3600)];
e2.name = @"e2";
Event *e3 = [Event new];
e3.eventDate = [NSDate dateWithTimeIntervalSinceNow:3600];
e3.name = @"e3";

NSArray *events = @[e1,e2,e3];
NSLog(@"Events = %@", events);
NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"eventDate.cbvTimeIntervalSinceStartOfDay" ascending:YES];
NSArray *sortedEvents = [events sortedArrayUsingDescriptors:@[sortDescriptor]];
NSLog(@"Sorted Events = %@", sortedEvents);

Executing this code presented the following output:

执行此代码时,输出如下:

2013-01-15 15:50:54.221 DateSortingFun[67319:c07] Events = (
    "<Event: 0x717b050>, name = e1, eventDate = Tuesday, January 15, 2013, 3:50:54 PM Mountain Standard Time",
    "<Event: 0x717b620>, name = e2, eventDate = Monday, January 14, 2013, 5:50:54 PM Mountain Standard Time",
    "<Event: 0x717b650>, name = e3, eventDate = Tuesday, January 15, 2013, 4:50:54 PM Mountain Standard Time" ) 


2013-01-15 15:50:54.222 DateSortingFun[67319:c07] Sorted Events = (
    "<Event: 0x717b050>, name = e1, eventDate = Tuesday, January 15, 2013, 3:50:54 PM Mountain Standard Time",
    "<Event: 0x717b650>, name = e3, eventDate = Tuesday, January 15, 2013, 4:50:54 PM Mountain Standard Time",
    "<Event: 0x717b620>, name = e2, eventDate = Monday, January 14, 2013, 5:50:54 PM Mountain Standard Time" )

#2


4  

use comparison blocks. and in the block create a new data with year, month and date set to the same day. that do a normal compare on those dates.

使用比较块。在块中创建新的数据,并将年、月和日期设置为同一天。在这些日期上做一个正常的比较。

    NSDateComponents *comps = [[NSDateComponents alloc] init];
    comps.year = 2007;
    comps.month = 12;
    comps.day = 3;
    comps.hour = 12;
    comps.minute = 3;

    NSDate *date1 = [[NSCalendar currentCalendar] dateFromComponents:comps];

    comps.year = 2012;
    comps.month = 9;
    comps.day = 7;
    comps.hour = 11;
    comps.minute = 13;

    NSDate *date2 = [[NSCalendar currentCalendar] dateFromComponents:comps];

    comps.year = 2021;
    comps.month = 12;
    comps.day = 3;
    comps.hour = 12;
    comps.minute = 5;

    NSDate *date3 = [[NSCalendar currentCalendar] dateFromComponents:comps];

    comps.year = 2021;
    comps.month = 12;
    comps.day = 3;
    comps.hour = 13;
    comps.minute = 5;


    NSDate *date4 = [[NSCalendar currentCalendar] dateFromComponents:comps];

    NSArray *dates = @[date1, date2, date3, date4];

    NSArray *oderedByTimeOnlyDates = [dates sortedArrayUsingComparator:^NSComparisonResult(NSDate *d1, NSDate *d2) {
        NSDateComponents *comps1 = [[NSCalendar currentCalendar] components:(NSHourCalendarUnit| NSMinuteCalendarUnit | NSSecondCalendarUnit)
                                                                  fromDate:d1];
        NSDateComponents *comps2 = [[NSCalendar currentCalendar] components:(NSHourCalendarUnit| NSMinuteCalendarUnit | NSSecondCalendarUnit)
                                                                   fromDate:d2];

        NSDate *date1 = [[NSCalendar currentCalendar] dateFromComponents:comps1];
        NSDate *date2 = [[NSCalendar currentCalendar] dateFromComponents:comps2];
        return [date1 compare:date2];
    }];

    NSLog(@"%@", oderedByTimeOnlyDates);

output:

输出:

(
    "2012-09-07 09:13:00 +0000",
    "2007-12-03 11:03:00 +0000",
    "2021-12-03 11:05:00 +0000",
    "2021-12-03 12:05:00 +0000"
)

The output is in UTC time, while they were created in UTC+1.

输出以UTC时间为单位,而它们是在UTC+1中创建的。