NSTimeInterval seems to be wrong for last day of t

2019-08-25 01:42发布

In my local database, I have a list of NSTimeInterval values saved. I have to find out and fetch all records available in a given Month. The only problem is in fetching records for last day of the given month seems to be unavailable.

Lets say given month is December so I have to fetch all the records from 1st Dec to 31st Dec (Till 11:59PM)

I am using following implementation:

[self.dateFormatter setDateFormat:@"dd-MM-yyyy"];
NSDate *startDate = [self.dateFormatter dateFromString:@"1-12-2012"];
NSDate *endDate = [self.dateFormatter dateFromString:@"31-12-2012"];

NSTimeInterval startDateTimeInterval = [startDate timeIntervalSince1970];
NSTimeInterval endDateTimeInterval = [endDate timeIntervalSince1970];

[fetchRequest setPredicate:[NSPredicate predicateWithFormat:@"(mdate >= %f) AND (mdate <= %f)",startDateTimeInterval,endDateTimeInterval]];

I have noticed that endDateTimeInterval double value is pretty less as compared to saved value in the database for 31st (9AM). But howz it possible, I am expecting my endDateTime should be till 31st Dec 11:59 PM.

Please provide your inputs on this issue.

2条回答
爷的心禁止访问
2楼-- · 2019-08-25 02:17

The NSDate objects you are creating implicitly have a time of 00:00. So the predicate search will not include the last day from time 00:01 to 23:59. The easiest change is to set the end date to the next day (first of next month) and change the predicate to a less than, instead of less than or equal.

[self.dateFormatter setDateFormat:@"dd-MM-yyyy"];
NSDate *startDate = [self.dateFormatter dateFromString:@"1-12-2012"]; // start of range, inclusive
NSDate *endDate = [self.dateFormatter dateFromString:@"1-1-2013"]; // end of range, exclusive
...        
[fetchRequest setPredicate:[NSPredicate predicateWithFormat:@"(mdate >= %f) AND (mdate < %f)",startDateTimeInterval,endDateTimeInterval]];
查看更多
太酷不给撩
3楼-- · 2019-08-25 02:31

Jason's answer will solve the problem but I think I've figured out the confusion: although in normal English a date usually specifies a whole day, in Cocoa terms an NSDate is an exact moment in time. So it has no length and a full description requires more detail than merely day/month/year. Most of the standard means of creating an NSDate offer precision to the nearest whole second, and obviously once you've converted to an 'NSTimeInterval` you can usually do better than that.

The NSLog is printing 30 because there are 30 whole days between the same time on the 1st of the month and the 31st, just like there's one whole day between the same time on the 1st and the 2nd, and zero whole days between the same time on the 1st and the 1st.

Jason's answer is therefore correct because it applies the time test of 'after the start of the first day of this month and before the start of the first day of the next month'. It's the 'the start of' bits that make the difference.

查看更多
登录 后发表回答