Comparing Nsdates Without Time Component

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



Leave a reply



Submit