从按格式化日期排序的核心数据中获取

发布于 2024-10-02 21:56:08 字数 1696 浏览 8 评论 0原文

我无法从核心数据中获取按日期排序的结果。

我有一个包含足球比赛的数据库表。每场比赛都有主队、客队和开球时间。 kickoffTime 是一个 NSDate,用于存储比赛开始的日期和时间。

我想在 TableView 中显示查询结果,按开始日期分为几个部分。以日期作为章节标题。

这比乍一看要复杂一些。由于时区不同,在世界某个地区的某个日期开始的比赛实际上在世界另一地区的不同日期开始。因此,我不能简单地忽略时间并将开始日期存储在另一列中。

我正在尝试创建一个自定义访问器,该访问器在用户所在的任何时区返回格式化日期,然后使用它对结果进行排序和分段。这是我在 Match.h 中的代码:

@dynamic kickoffTime;
@dynamic formattedKickoffTime;
@dynamic dateFormatter;

- (NSString *)formattedKickoffTime
{
    [self willAccessValueForKey:@"kickoffTime"];

    // Set the date formatter to the format we want to display the date
    [dateFormatter setDateFormat:@"ccc, d MMM"];

    // Format the date
    NSString *myFormattedKickoffTime = [dateFormatter stringFromDate:[self kickoffTime]];

    [self didAccessValueForKey:@"kickoffTime"];

    // return the formatted date
    return myFormattedKickoffTime;
}

- (NSDateFormatter *)dateFormatter 
{   
    if (dateFormatter == nil) 
    {
        dateFormatter = [[NSDateFormatter alloc] init];
    }
    return dateFormatter;
}

@end

但是,当我尝试像这样获取和排序数据时:

NSSortDescriptor *kickoffDescriptor = [[NSSortDescriptor alloc] initWithKey:@"formattedKickoffTime" ascending:YES];
...
NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:appDelegate.managedObjectContext sectionNameKeyPath:@"formattedKickoffTime" cacheName:nil];

我收到以下错误消息:

*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'keypath formattedKickoffTime not found in entity <NSSQLEntity Match id=1>'

有人会提供一些建议吗?

I am having trouble fetching results from Core Data that are sorted by date.

I have a DB table that contains football matches. Each match has a homeTeam, awayTeam and kickoffTime. The kickoffTime is an NSDate that stores the date and time the match will start.

I want to display the results of a query in a TableView divided into sections by the kickoff date. With the date as the section heading.

This is a little more complex than it might first appear. Due to differing time zones a match starting on one date in one part of the world is actually starting on a different date in another part of the world. So I can't simply ignore the times and store the kickoff dates in another column.

What I'm trying to do create a custom accessor that returns a formatted date, in whatever time zone the user is in, and then use this to sort and section the results. Here's my code in Match.h:

@dynamic kickoffTime;
@dynamic formattedKickoffTime;
@dynamic dateFormatter;

- (NSString *)formattedKickoffTime
{
    [self willAccessValueForKey:@"kickoffTime"];

    // Set the date formatter to the format we want to display the date
    [dateFormatter setDateFormat:@"ccc, d MMM"];

    // Format the date
    NSString *myFormattedKickoffTime = [dateFormatter stringFromDate:[self kickoffTime]];

    [self didAccessValueForKey:@"kickoffTime"];

    // return the formatted date
    return myFormattedKickoffTime;
}

- (NSDateFormatter *)dateFormatter 
{   
    if (dateFormatter == nil) 
    {
        dateFormatter = [[NSDateFormatter alloc] init];
    }
    return dateFormatter;
}

@end

However when I try to fetch and sort the data like so:

NSSortDescriptor *kickoffDescriptor = [[NSSortDescriptor alloc] initWithKey:@"formattedKickoffTime" ascending:YES];
...
NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:appDelegate.managedObjectContext sectionNameKeyPath:@"formattedKickoffTime" cacheName:nil];

I get the following error message:

*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'keypath formattedKickoffTime not found in entity <NSSQLEntity Match id=1>'

Would someone offer some advice please?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

佼人 2024-10-09 21:56:08

所以我找到了一种方法来做到这一点。首先,我将模型中的所有日期和计算保留为 GMT。我将自定义访问器 (kickoffDate) 添加到我的 Match 实体中,该实体获取 kickoffTime、将时间设置为 00:00:00 并返回该值。我必须做的一件事(并不明显)是将自定义访问器返回的日期的时区设置为 GMT,否则这将被设置为用户的系统时区。

由于模型返回的所有日期均为 GMT,因此无论我在 iPhone 设置中设置哪个时区,一切似乎都正常工作。我猜 Core Data 足够聪明,可以在将匹配项放入各部分之前进行时区调整。

我确实有一个问题,[NSTimeZone timeZoneForSecondsFromGMT:0] 是获得 0 时区的最佳方法吗?我的意思是不受夏令时影响的时区?

哦,我必须调用 [self willAccessValueForKey:@"kickoffTime"];[self didAccessValueForKey:@"kickoffTime"]; 吗?实在不明白这些人在做什么!

这是 Match.h 中的代码:

...
@dynamic homeTeam;
@dynamic awayTeam;
@dynamic kickoffTime;

- (NSDate *)kickoffDate
{
    [self willAccessValueForKey:@"kickoffTime"];
    NSCalendar *cal = [NSCalendar currentCalendar];
    NSDateComponents *components = [cal components:(NSYearCalendarUnit|NSMonthCalendarUnit|NSDayCalendarUnit) fromDate:[self primitiveValueForKey:@"kickoffTime"]];
    [components setHour:0];
    [components setMinute:0];
    [components setSecond:0];
    [components setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0]];

    [self didAccessValueForKey:@"kickoffTime"];
    return [cal dateFromComponents:components];
}

然后我的获取代码包括以下对 kickoffTime 进行排序的内容,并将sectionNameKeyPath 设置为 kickoffDate:

NSSortDescriptor *kickoffDescriptor = [[NSSortDescriptor alloc] initWithKey:@"kickoffTime" ascending:YES];
...
NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:appDelegate.managedObjectContext sectionNameKeyPath:@"kickoffDate" cacheName:nil];

So I've found a way to do this. First of all I keep all the dates and calculations in the model in GMT. I add a custom accessor (kickoffDate) to my Match entity that gets the kickoffTime, sets it's time to 00:00:00 and returns this. One thing I had to do, that wasn't obvious, was set the timeZone of the date returned by the custom accessor to GMT as otherwise this was being set to the user's system timeZone.

As all the dates returned by the model are in GMT everything just seems to work as it should no matter what timeZone I set in the iPhone's Settings. I guess Core Data is smart enough to do the timeZone adjustments before it puts the matches in the sections.

I do have one question though, is [NSTimeZone timeZoneForSecondsFromGMT:0] the best way to get a 0 timeZone, by this I mean a timeZone that isn't affected by daylight saving time?

Oh and do I have to call [self willAccessValueForKey:@"kickoffTime"]; and [self didAccessValueForKey:@"kickoffTime"];? I don't really understand what these are doing!

Here's the code in Match.h:

...
@dynamic homeTeam;
@dynamic awayTeam;
@dynamic kickoffTime;

- (NSDate *)kickoffDate
{
    [self willAccessValueForKey:@"kickoffTime"];
    NSCalendar *cal = [NSCalendar currentCalendar];
    NSDateComponents *components = [cal components:(NSYearCalendarUnit|NSMonthCalendarUnit|NSDayCalendarUnit) fromDate:[self primitiveValueForKey:@"kickoffTime"]];
    [components setHour:0];
    [components setMinute:0];
    [components setSecond:0];
    [components setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0]];

    [self didAccessValueForKey:@"kickoffTime"];
    return [cal dateFromComponents:components];
}

And then my fetch code includes the following a sort on kickoffTime and the sectionNameKeyPath is set to kickoffDate:

NSSortDescriptor *kickoffDescriptor = [[NSSortDescriptor alloc] initWithKey:@"kickoffTime" ascending:YES];
...
NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:appDelegate.managedObjectContext sectionNameKeyPath:@"kickoffDate" cacheName:nil];
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文