Cocoa-Touch: How do I see if two NSDates are in the same day?

后端 未结 12 616
走了就别回头了
走了就别回头了 2020-11-30 04:35

I need to know if two NSDate instances are both from the same day.

Is there an easier/better way to do it than getting the NSDateComponents and comparing day/month/y

相关标签:
12条回答
  • 2020-11-30 04:54

    Is there an easier/better way to do it than getting the NSDateComponents and comparing day/month/year?

    Yes, there is an easier way

    -[NSCalendar rangeForUnit:startDate:interval:forDate:] This methods makes it easy to set a date to a beginning of a unit (day, hour, month, year,…) and get the length (interval) of that unit.

    As a category it might be used like

    @interface NSDate (Comparison)
    -(BOOL) isSameDay:(NSDate *)rhs;
    @end
    
    @implementation NSDate (Comparison)
    
    -(BOOL)isSameDay:(NSDate *)rhs
    {
        NSDate *lhs = self;
        NSDate *lhsStart;
        NSDate *rhsStart;
    
        NSCalendar *cal = [NSCalendar currentCalendar];
        [cal rangeOfUnit:NSCalendarUnitDay startDate:&lhsStart interval:NULL forDate:lhs];
        [cal rangeOfUnit:NSCalendarUnitDay startDate:&rhsStart interval:NULL forDate:rhs];
        return [lhsStart compare:rhsStart] == NSOrderedSame;
    }
    
    @end
    

    This category should work for all iOS versions and Mac OS X 10.5+.

    for iOS 8+ and Mac OS X 10.9+, you can use NSCalendars

    - (BOOL)isDate:(NSDate *)date1 equalToDate:(NSDate *)date2 toUnitGranularity:(NSCalendarUnit)unit;
    
    0 讨论(0)
  • 2020-11-30 04:56

    (Note: Look at Joe's answer for a good way to do this on iOS 8+)

    I just use a date formatter:

    NSDateFormatter *dateComparisonFormatter = [[[NSDateFormatter alloc] init] autorelease];
    [dateComparisonFormatter setDateFormat:@"yyyy-MM-dd"];
    
    if( [[dateComparisonFormatter stringFromDate:firstDate] isEqualToString:[dateComparisonFormatter stringFromDate:secondDate]] ) {
        …
    }
    

    HTH.

    0 讨论(0)
  • 2020-11-30 04:58

    In Swift:

    NSCalendar.currentCalendar().isDate(yourDate, equalToDate: yourOtherDate, toUnitGranularity: .Day)
    

    It will return true if they are on the same day.

    0 讨论(0)
  • 2020-11-30 04:59

    I like progrmr's solution, but I would go even further and make a category of NSDate that provides this method. It will make your code slightly more readable, and you won't need to copy and paste the method into each new class that might need it – just import the header file.

    NSDate+SameDay.h

    @interface NSDate (SameDay)
    - (BOOL)isSameDayAsDate:(NSDate*)otherDate;
    @end
    

    NSDate+SameDay.m

    #import "NSDate+SameDay.h"
    
    @implementation NSDate (SameDay)
    
    - (BOOL)isSameDayAsDate:(NSDate*)otherDate {
    
        // From progrmr's answer...
        NSCalendar* calendar = [NSCalendar currentCalendar];
    
        unsigned unitFlags = NSYearCalendarUnit | NSMonthCalendarUnit |  NSDayCalendarUnit;
        NSDateComponents* comp1 = [calendar components:unitFlags fromDate:self];
        NSDateComponents* comp2 = [calendar components:unitFlags fromDate:otherDate];
    
        return [comp1 day]   == [comp2 day] &&
               [comp1 month] == [comp2 month] &&
               [comp1 year]  == [comp2 year];
    }
    
    @end
    

    Then, after importing NSDate+SameDay.h in your class, you can use it like so:

    if ([myFirstDate isSameDayAsDate:mySecondDate]) {
        // The two dates are on the same day...
    }
    
    0 讨论(0)
  • 2020-11-30 05:00

    I use NSDateComponents to strip out the time aspect and then compare. Something like:

    if ([[self beginningOfDay:date1] isEqualToDate:[self beginningOfDay:date2]]) 
    {
    ...
    }
    
    - (NSDate *)beginningOfDay:(NSDate *)date {
        NSCalendar *calendar = [NSCalendar currentCalendar];
    
        unsigned unitFlags = NSYearCalendarUnit | NSMonthCalendarUnit |  NSDayCalendarUnit;
        NSDateComponents *comp = [calendar components:unitFlags fromDate:date];
    
        return [calendar dateFromComponents:comp];
    }
    
    0 讨论(0)
  • 2020-11-30 05:01

    If you are targeting iOS 8 (and OS X 10.9) or later, then Joe's answer is a better solution using a new method in NSCalendar just for this purpose:

    -[NSCalendar isDate:inSameDayAsDate:]
    

    For iOS 7 or earlier: NSDateComponents is my preference. How about something like this:

    - (BOOL)isSameDayWithDate1:(NSDate*)date1 date2:(NSDate*)date2 {
        NSCalendar* calendar = [NSCalendar currentCalendar];
    
        unsigned unitFlags = NSYearCalendarUnit | NSMonthCalendarUnit |  NSDayCalendarUnit;
        NSDateComponents* comp1 = [calendar components:unitFlags fromDate:date1];
        NSDateComponents* comp2 = [calendar components:unitFlags fromDate:date2];
    
        return [comp1 day]   == [comp2 day] &&
               [comp1 month] == [comp2 month] &&
               [comp1 year]  == [comp2 year];
    }
    
    0 讨论(0)
提交回复
热议问题