【问题标题】:Core Data group by NSDate without TimeNSDate without Time 的核心数据组
【发布时间】:2021-12-23 16:33:21
【问题描述】:

我在核心数据中有开始日期属性,我想获取项目以及根据开始日期分组,

但是 startDate 里面基本上有 timeComponent,但是我希望分组是基于 yyyy-mm-dd,

这是我正在使用的代码

    NSError *error = nil;
    NSFetchRequest *request = [NSFetchRequest new];
    NSManagedObjectContext *context = self.managedObjectContext;
    request.entity = [CalendarItem entityInManagedObjectContext:context];
    NSExpression *startExpr = [NSExpression expressionForKeyPath:@"start"];
    NSExpression *countExpr = [NSExpression expressionForFunction:@"count:" arguments:[NSArray arrayWithObject:startExpr]];
    NSExpressionDescription *exprDesc = [[NSExpressionDescription alloc] init];
    [exprDesc setExpression:countExpr];
    [exprDesc setExpressionResultType:NSInteger64AttributeType];
    [exprDesc setName:@"count"];
    
    [request setPropertiesToGroupBy:@[@"start"]];
    [request setPropertiesToFetch:[NSArray arrayWithObjects:@"start", exprDesc, nil]];
    [request setResultType:NSDictionaryResultType];
    NSArray *results = [self.managedObjectContext executeFetchRequest:request error:&error];

这是我得到的输出:

Printing description of results:
<_PFArray 0x600001e3a700>(
{
    count = 1;
    start = "2021-09-14 03:30:00 +0000";
},
{
    count = 1;
    start = "2021-09-14 04:00:00 +0000";
},
{
    count = 1;
    start = "2021-09-16 09:30:00 +0000";
},
{
    count = 1;
    start = "2021-11-11 00:00:00 +0000";
},
{
    count = 1;
    start = "2021-11-11 04:00:00 +0000";
},
{
    count = 1;
    start = "2021-11-11 06:00:00 +0000";
},
{
    count = 1;
    start = "2021-11-12 00:00:00 +0000";
}
)

预期结果:

{
    count = 2
    start = 2021-09-14
}
{
    count = 1
    start = 2021-09-16
}
{
    count = 3
    start = 2021-11-11
}
{
    count = 1;
    start = "2021-11-12
}

【问题讨论】:

  • 日志中的打印描述无关紧要。只需忽略您将要使用的时间组件startDate
  • 我需要根据 startDate 没有 timeComponent 对事件进行分组,请查看预期结果以获得更清晰的结果
  • 可以使用NSCalendar的dateBySettingHour:minute:second:ofDate:options:
  • 对不起@Cy-4AH,但我不明白你的意思,实际上我希望 NSFetchRequest 返回预期结果,即按 start(withoutTimeComponents) 计数 + 开始组,我希望现在我已经清楚地问了我的疑惑
  • 然后用dateBySettingHour:minute:second:ofDate:options: 删除时间组件。您可以创建只读属性,例如:startDateOnly

标签: objective-c core-data nsdate


【解决方案1】:

如您所见,Core Data 的“日期”属性实际上是时间戳。它们包括一天中的时间,即使它们被称为“日期”。你不能告诉 Core Data 只使用日期属性的部分值——要么全有,要么全无。

要获得所需的分组类型,您需要创建另一个属性,其中的值仅是您需要的值,而不是包含您不需要的额外详细信息的时间戳。在这里,这将是一个小时、分钟和秒都设置为零的日期,因此这些细节不会影响分组。

一种方法是使用该更改创建一个新的日期对象并将其保存在一个新属性中。你可以称它为trimmedDate。然后,每当您在实例上设置日期时,也要设置 trimmedDate,使用类似于

的代码
NSDate *trimmed = [[NSCalendar currentCalendar] dateBySettingHour:0 minute:0 second:0 ofDate:date options:0];

然后使用这个新值进行分组。

【讨论】:

  • Tom 有什么方法可以在 NSExpression 中为核心 Data 属性使用自定义函数,即可以使用我自己创建的方法在获取时从 Core Data 属性中提取日期(没有时间组件)
  • 不使用 SQLite 存储。该表达式由 SQLite 评估,因此它需要是 SQLite 知道的内容。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多