Comparing two NSDates and ignoring the time component
You set the time in the date to 00:00:00 before doing the comparison:
unsigned int flags = NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay;
NSCalendar* calendar = [NSCalendar currentCalendar];
NSDateComponents* components = [calendar components:flags fromDate:date];
NSDate* dateOnly = [calendar dateFromComponents:components];
// ... necessary cleanup
Then you can compare the date values. See the overview in reference documentation.
Comparing NSDates without time component
Use this Calendar
function to compare dates in iOS 8.0+
func compare(_ date1: Date, to date2: Date, toGranularity component: Calendar.Component) -> ComparisonResult
passing .day
as the unit
Use this function as follows:
let now = Date()
// "Sep 23, 2015, 10:26 AM"
let olderDate = Date(timeIntervalSinceNow: -10000)
// "Sep 23, 2015, 7:40 AM"
var order = Calendar.current.compare(now, to: olderDate, toGranularity: .hour)
switch order {
case .orderedDescending:
print("DESCENDING")
case .orderedAscending:
print("ASCENDING")
case .orderedSame:
print("SAME")
}
// Compare to hour: DESCENDING
var order = Calendar.current.compare(now, to: olderDate, toGranularity: .day)
switch order {
case .orderedDescending:
print("DESCENDING")
case .orderedAscending:
print("ASCENDING")
case .orderedSame:
print("SAME")
}
// Compare to day: SAME
iOS: Compare two NSDate-s without time portion
NSCalendar *calendar = [NSCalendar currentCalendar];
NSInteger comps = (NSCalendarUnitDay | NSCalendarUnitMonth | NSCalendarUnitYear);
NSDateComponents *date1Components = [calendar components:comps
fromDate: date1];
NSDateComponents *date2Components = [calendar components:comps
fromDate: date2];
date1 = [calendar dateFromComponents:date1Components];
date2 = [calendar dateFromComponents:date2Components];
NSComparisonResult result = [date1 compare:date2];
if (result == NSOrderedAscending) {
} else if (result == NSOrderedDescending) {
} else {
//the same
}
There is another handy method to create for a given date the date that represents the start of a given unit: [aCalendar rangeOfUnit:startDate:interval:forDate:]
To illustrate how this method works, see this code, that easily creates the date for the beginning of the day, week, month and year for a given date (here: now).
NSDate *now = [NSDate date];
NSDate *startOfToday = nil;
NSDate *startOfThisWeek = nil;
NSDate *startOfThisMonth = nil;
NSDate *startOfThisYear = nil;
[[NSCalendar currentCalendar] rangeOfUnit:NSDayCalendarUnit startDate:&startOfToday interval:NULL forDate:now];
[[NSCalendar currentCalendar] rangeOfUnit:NSWeekCalendarUnit startDate:&startOfThisWeek interval:NULL forDate:now];
[[NSCalendar currentCalendar] rangeOfUnit:NSMonthCalendarUnit startDate:&startOfThisMonth interval:NULL forDate:now];
[[NSCalendar currentCalendar] rangeOfUnit:NSYearCalendarUnit startDate:&startOfThisYear interval:NULL forDate:now];
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateStyle:NSDateFormatterFullStyle];
[formatter setTimeStyle:NSDateFormatterFullStyle];
NSLog(@"%@", [formatter stringFromDate:now]);
NSLog(@"%@", [formatter stringFromDate:startOfToday]);
NSLog(@"%@", [formatter stringFromDate:startOfThisWeek]);
NSLog(@"%@", [formatter stringFromDate:startOfThisMonth]);
NSLog(@"%@", [formatter stringFromDate:startOfThisYear]);
result:
Thursday, July 12, 2012, 4:36:07 PM Central European Summer Time
Thursday, July 12, 2012, 12:00:00 AM Central European Summer Time
Sunday, July 8, 2012, 12:00:00 AM Central European Summer Time
Sunday, July 1, 2012, 12:00:00 AM Central European Summer Time
Sunday, January 1, 2012, 12:00:00 AM Central European Standard Time
this allows us to shorten the first code to:
[[NSCalendar currentCalendar] rangeOfUnit:NSDayCalendarUnit startDate:&date1 interval:NULL forDate:date1];
[[NSCalendar currentCalendar] rangeOfUnit:NSDayCalendarUnit startDate:&date2 interval:NULL forDate:date2];
NSComparisonResult result = [date1 compare:date2];
if (result == NSOrderedAscending) {
} else if (result == NSOrderedDescending) {
} else {
//the same
}
Note, that in this code, date1
and date2
will be overwritten. Alternatively you can pass in a reference to another NSDate pointer for startDate
as shown in the code above, where now
stays untouched.
Comparing the time of two NSDates, ignoring the date component
unsigned int flags = NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitSecond;
NSCalendar* calendar = [NSCalendar currentCalendar];
NSDateComponents* components = [calendar components:flags fromDate:date1];
NSDate* timeOnly = [calendar dateFromComponents:components];
This will give you a date object where everything but the hours/minutes/seconds have been reset to some common value. Then you can use the standard NSDate compare functions on them.
For reference, here is the opposite question to yours: Comparing two NSDates and ignoring the time component
Cocoa-Touch: How do I see if two NSDates are in the same day?
NSDateComponents sounds like the best bet to me. Another tactic to try is toll-free-bridging it to a CFDate, then using CFDateGetAbsoluteTime and doing a subtraction to get the amount of time between the two dates. You'll have to do some additional math to figure out if the time difference lands the dates on the same day, however.
Objective C how to compare two date_time with the ignorance on second value
Nowadays, probably the best way is to use -[NSCalendar isDate:equalToDate:toUnitGranularity:]
.
BOOL datesAreEqual = [[NSCalendar currentCalendar] isDate:date1
equalToDate:date2 toUnitGranularity:NSCalendarUnitMinute];
To compare them (find out which one is more recent/late), use -[NSCalendar compareDate:toDate:toUnitGranularity:]
instead.
Possible to compare NSDate objects without using calendar components?
Yes, absolutely. There are an endless number of pitfalls with date math. Use NSDateComponents; they’re not hard.
NSCalendar *cal = [NSCalendar currentCalendar];
NSDateComponents *date1Components = [cal components:NSEraCalendarUnit | NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit fromDate:date1];
NSDateComponents *date2Components = [cal components:NSEraCalendarUnit | NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit fromDate:date2];
NSComparisonResult comparison = [[cal dateFromComponents:date1Components] compare:[cal dateFromComponents:date2Components];
Comparing two NSDates date and time ignoring seconds
This seems to be working solution as of now. If anyone gets better one do post it.
-(BOOL)checkIfTimePassed{
NSDate *today = [NSDate date];
NSComparisonResult result = [[NSCalendar currentCalendar] compareDate:today toDate:self.whenDate toUnitGranularity:NSCalendarUnitMinute];
if(result==NSOrderedAscending){
NSLog(@"today is less");
return NO;
}
else if(result==NSOrderedDescending)
{
NSLog(@"newDate is less");
return YES;
}
else
{
NSLog(@"Both dates are same");
return NO;
}
}
How to check if two NSDates are from the same day
NSCalendar has a method that does exactly what you want actually!
/*
This API compares the Days of the given dates, reporting them equal if they are in the same Day.
*/
- (BOOL)isDate:(NSDate *)date1 inSameDayAsDate:(NSDate *)date2 NS_AVAILABLE(10_9, 8_0);
So you'd use it like this:
[[NSCalendar currentCalendar] isDate:date1 inSameDayAsDate:date2];
Or in Swift
Calendar.current.isDate(date1, inSameDayAs:date2)
Related Topics
Update Restkit 'Lcl_Rk.H' File Not Found in Rklog.H
How to Detect the Touch Event of an Uiimageview
How to Get Unique Id in iOS Device
Detecting Collisions in Sprite Kit
Long Press Gesture on Uicollectionviewcell
How to Get Uikeyboard Size with iOS
Objective-C Declare Vars with ({ ... })
Retrieve All Contacts Phone Numbers in iOS
Xcode - Ld: Library Not Found for -Lpods
Crashlytics: "We'Re Missing a Dsym to Process Crashes"
How to Insert the Uitextview into Uialertview in iOS
How to Check If a View Controller Is Presented Modally or Pushed on a Navigation Stack
Xcode 6.1 Missing Required Architecture X86_64 in File
How to Know If Two Emojis Will Be Displayed as One Emoji