我敢肯定这个问题在我拔头发之前就出现了。我有两个日期 - 一个来自 Parse.com 上的对象,另一个来自本地日期。我尝试确定远程对象是否已更新,以便我可以在本地触发操作。
当查看两个对象的 NSDate 时,它们看起来相同,但比较显示远程对象较新 - 当检查内部时间(自 1970 年以来(时,很明显存在差异,但为什么?当我第一次创建本地对象时,我所做的只是
localObject.updatedAt = remoteObject.updatedAt //both NSDate
但是当仔细观察时,我得到这个:
Local Time Interval: 1411175940.000000
Local Time: 2014-09-20 01:19:00 +0000
Remote Time Interval: 1411175940.168000
Remote Time: 2014-09-20 01:19:00 +0000
有没有人知道为什么会这样,我是否可以忽略这个细节?iOS 会四舍五入还是什么?
添加更多代码:
@property (strong, nonatomic) NSDate *date;
...
PFQuery *query = [PFObject query];
[query whereKey:@"Product" equalTo:@"123456"]
[query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
if (!error)
{
self.date = objects[0].updatedAt;
NSTimeInterval localTime = [self.date timeIntervalSince1970];
NSTimeInterval remoteTime = [objects[0].updatedAt timeIntervalSince1970];
NSLog(@"Local Time Interval: %f", localTime);
NSLog(@"Local Time: %@", self.date);
NSLog(@"Remote Time Interval: %f", remoteTime);
NSLog(@"Remote Time: %@", objects[0].updatedAt);
}
else
{
NSLog(@"Error with query");
}
}];
这导致了上面的控制台输出 - 我不明白为什么这些日期不同。
我无法解释为什么会有差异,但重要的是要了解可能存在差异,并且在比较日期时必须使用容差值。
Apple 日期和时间编程指南有一个示例,说明如何在给定容差内比较两个日期:
要比较日期,可以使用
isEqualToDate:
、compare:
、laterDate:
和earlierDate:
方法。这些方法执行精确 比较,这意味着它们检测到亚秒级差异 日期。您可能希望比较粒度不太细的日期。为 例如,如果两个日期位于 彼此的分钟。如果是这种情况,请使用timeIntervalSinceDate:
以比较两个日期。以下代码片段演示如何使用timeIntervalSinceDate:
查看两个日期是否在一分钟内 (60 秒(彼此。if (fabs([date2 timeIntervalSinceDate:date1]) < 60) ...
公差值由您决定,但 0.5 秒左右似乎是合理的:
+ (BOOL)date:(NSDate *)date1
equalsDate:(NSDate *)date2
{
return fabs([date2 timeIntervalSinceDate:date1]) < 0.5;
}
日期存储为 iso8601 格式。这使得事情变得非常复杂,因为Apple不能很好地管理格式。虽然标准的想法很棒,但在每个人都按照相同的规则行事之前,无政府状态规则。
我将所有入站内容从解析转换为可用格式,然后再尝试使用其日期时间值进行任何操作。
把它放到某个地方的图书馆里,省去很多麻烦。这需要数周的搜索和抓挠才能克服。
+ (NSDate *)convertParseDate:(NSDate *)sourceDate {
NSDateFormatter *dateFormatter = [NSDateFormatter new];
NSString *input = (NSString *)sourceDate;
dateFormatter.dateFormat = @"yyyy-MM-dd'T'HH:mm:ss.SSS'Z'";
// Always use this locale when parsing fixed format date strings
NSLocale* posix = [[NSLocale alloc] initWithLocaleIdentifier:@"en_US_POSIX"];
dateFormatter.locale = posix;
NSDate *convertedDate = [dateFormatter dateFromString:input];
assert(convertedDate != nil);
return convertedDate;
}