如何在 Realm 中通过 NSDate 属性 正确查询对象?
How to query object by NSDate property correctly in Realm?
我有以下场景,我在 Realm 上存储了一个包含当前日期的对象,如下所示:
RLMChatMessage *chat = [[RLMChatMessage alloc] init];
chat.chatFrom = from;
chat.chatTo = to;
chat.timeStamp = [NSDate date];
RLMRealm *realm = [RLMRealm defaultRealm];
[realm transactionWithBlock: ^{
[realm addObject: chat];
}];
为了将时间戳发送到服务器,我将其转换为 NSString,如下所示:
NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
[dateFormat setDateFormat: @"YYYYMMddHHmmssSSS”]; // Capital ’S’ is milliseconds
[dateFormat setTimeZone:[NSTimeZone timeZoneWithName:@"UTC"]];
return [dateFormat stringFromDate: date];
NSString中时间戳的结果为:20190612090741181,格式为"YYYYMMddHHmmssSSS"。
当我收到特定时间戳的确认消息时,我将 NSString 转换回 NSDate:
NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
[dateFormat setDateFormat: @"YYYYMMddHHmmssSSS”];
[dateFormat setTimeZone:[NSTimeZone timeZoneWithName:@"UTC"]];
return [dateFormat dateFromString: strTime];
我用时间戳(用上面的代码创建的 NSDate 对象)查询聊天如下:
RLMResults *results = [RLMChatMessage objectsWhere:@"timeStamp == %@", date];
return results.firstObject;
遗憾的是,结果没有找到对象。不知何故,Realm 似乎无法找到具有提供的 NSDate 时间戳的聊天对象。
使用 Realm Browser 应用程序查看数据库,我可以看到带有以下 NSDate 的 NSDate 属性:
Xcode 中用于将 NSString 时间戳转换为 NSDate 的 NSLog 输出如下所示:
因此两者显示的 NSDate 时间戳相同。我假设两者都将 NSDate 对象打印到我机器的本地时间。那么,为什么 Realm 找不到聊天对象呢?我有点迷路了。希望有人能帮帮我。
我找到了解决方案,似乎将格式为“YYYYMMddHHmmssSSS”的 NSString 时间转换为 NSDate 会丢失一些信息或准确性。
因此,存储在数据库中的原始 NSDate 对象与从 NSString 转换而来的对象不匹配。因此,我没有像这样用当前时间分配时间戳:[NSDate date],而是重新创建一个格式为“YYYYMMddHHmmssSSS”的新 NSDate 对象,如下所示:
- (NSDate*) timeStampNowWithFormat: (NSString*) format {
NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
[dateFormat setDateFormat: format];
[dateFormat setTimeZone:[NSTimeZone timeZoneWithName:@"UTC"]];
NSString *stringDate = [dateFormat stringFromDate: [NSDate date]];
return [dateFormat dateFromString: stringDate];
}
// ...
// ...
RLMChatMessage *chat = [[RLMChatMessage alloc] init];
chat.chatFrom = from;
chat.chatTo = to;
chat.timeStamp = [self timeStampNowWithFormat: @"YYYYMMddHHmmssSSS"];
RLMRealm *realm = [RLMRealm defaultRealm];
[realm transactionWithBlock: ^{
[realm addObject: chat];
}];
最重要的是,一旦您将 NSDate 对象转换为 NSString,然后从该 NSString 重新创建一个新的 NSDate,如果时间精度小于毫秒(即微秒),则两个 NSDate 对象将不再相等。
我花了一天多的时间才弄明白。
我有以下场景,我在 Realm 上存储了一个包含当前日期的对象,如下所示:
RLMChatMessage *chat = [[RLMChatMessage alloc] init];
chat.chatFrom = from;
chat.chatTo = to;
chat.timeStamp = [NSDate date];
RLMRealm *realm = [RLMRealm defaultRealm];
[realm transactionWithBlock: ^{
[realm addObject: chat];
}];
为了将时间戳发送到服务器,我将其转换为 NSString,如下所示:
NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
[dateFormat setDateFormat: @"YYYYMMddHHmmssSSS”]; // Capital ’S’ is milliseconds
[dateFormat setTimeZone:[NSTimeZone timeZoneWithName:@"UTC"]];
return [dateFormat stringFromDate: date];
NSString中时间戳的结果为:20190612090741181,格式为"YYYYMMddHHmmssSSS"。
当我收到特定时间戳的确认消息时,我将 NSString 转换回 NSDate:
NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
[dateFormat setDateFormat: @"YYYYMMddHHmmssSSS”];
[dateFormat setTimeZone:[NSTimeZone timeZoneWithName:@"UTC"]];
return [dateFormat dateFromString: strTime];
我用时间戳(用上面的代码创建的 NSDate 对象)查询聊天如下:
RLMResults *results = [RLMChatMessage objectsWhere:@"timeStamp == %@", date];
return results.firstObject;
遗憾的是,结果没有找到对象。不知何故,Realm 似乎无法找到具有提供的 NSDate 时间戳的聊天对象。
使用 Realm Browser 应用程序查看数据库,我可以看到带有以下 NSDate 的 NSDate 属性:
Xcode 中用于将 NSString 时间戳转换为 NSDate 的 NSLog 输出如下所示:
因此两者显示的 NSDate 时间戳相同。我假设两者都将 NSDate 对象打印到我机器的本地时间。那么,为什么 Realm 找不到聊天对象呢?我有点迷路了。希望有人能帮帮我。
我找到了解决方案,似乎将格式为“YYYYMMddHHmmssSSS”的 NSString 时间转换为 NSDate 会丢失一些信息或准确性。 因此,存储在数据库中的原始 NSDate 对象与从 NSString 转换而来的对象不匹配。因此,我没有像这样用当前时间分配时间戳:[NSDate date],而是重新创建一个格式为“YYYYMMddHHmmssSSS”的新 NSDate 对象,如下所示:
- (NSDate*) timeStampNowWithFormat: (NSString*) format {
NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
[dateFormat setDateFormat: format];
[dateFormat setTimeZone:[NSTimeZone timeZoneWithName:@"UTC"]];
NSString *stringDate = [dateFormat stringFromDate: [NSDate date]];
return [dateFormat dateFromString: stringDate];
}
// ...
// ...
RLMChatMessage *chat = [[RLMChatMessage alloc] init];
chat.chatFrom = from;
chat.chatTo = to;
chat.timeStamp = [self timeStampNowWithFormat: @"YYYYMMddHHmmssSSS"];
RLMRealm *realm = [RLMRealm defaultRealm];
[realm transactionWithBlock: ^{
[realm addObject: chat];
}];
最重要的是,一旦您将 NSDate 对象转换为 NSString,然后从该 NSString 重新创建一个新的 NSDate,如果时间精度小于毫秒(即微秒),则两个 NSDate 对象将不再相等。 我花了一天多的时间才弄明白。