首页 文章

Cocoa-Touch:我如何看待两个NSD在同一天?

提问于
浏览
67

我需要知道两个NSDate实例是否都来自同一天 .

有没有比获得NSDateComponents和比较日/月/年更容易/更好的方法呢?

12 回答

  • 7

    在Swift中:

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

    如果它们在同一天,它将返回true .

  • 154

    NSDateComponents听起来对我来说是最好的选择 . 另一种尝试的策略是免费将其桥接到CFDate,然后使用CFDateGetAbsoluteTime并进行减法以获得两个日期之间的时间量 . 然而,你必须做一些额外的数学计算,以确定时差是否在同一天登陆日期 .

  • 1

    如果你的目标是 iOS 8 (and OS X 10.9) or later ,那么Joe's answer是一个更好的解决方案,使用NSCalendar中的新方法就是为了这个目的:

    -[NSCalendar isDate:inSameDayAsDate:]
    

    For iOS 7 or earlier :NSDateComponents是我的偏好 . 这样的事情怎么样:

    - (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];
    }
    
  • 1

    如果您使用的是iOS 8,则可以使用 -isDate:inSameDayAsDate: .

    来自 NSCalendar.h

    /*
        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);
    

    请注意,由于某些原因,这不适用于Apple开发者网站上的官方文档 . 但它肯定是公共API的一部分 .

  • 11

    (注意:看看Joe的答案是否能在iOS 8上做到这一点)

    我只使用日期格式化程序:

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

    HTH .

  • 24

    我喜欢progrmr的解决方案,但我会更进一步,制作一个提供此方法的 NSDate 类别 . 它将使您的代码稍微更具可读性,并且您不需要将该方法复制并粘贴到可能需要它的每个新类中 - 只需导入头文件即可 .

    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
    

    然后,在您的类中导入 NSDate+SameDay.h 之后,您可以像这样使用它:

    if ([myFirstDate isSameDayAsDate:mySecondDate]) {
        // The two dates are on the same day...
    }
    
  • 5

    我使用NSDateComponents去除时间方面然后进行比较 . 就像是:

    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];
    }
    
  • 4
    NSCalendar.currentCalendar().isDateInToday(yourNSDate)
    

    适用于iOS 8.0及更高版本以及OS X v10.9及更高版本 .

  • 13

    有没有比获得NSDateComponents和比较日/月/年更容易/更好的方法呢?

    是的,有一种更简单的方法

    -[NSCalendar rangeForUnit:startDate:interval:forDate:] 此方法可以轻松地将日期设置为单位的开头(日,小时,月,年......)并获取该单位的长度(间隔) .

    作为一个类别,它可能会被用作

    @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
    

    此类别适用于所有iOS版本和Mac OS X 10.5 .

    对于iOS 8和Mac OS X 10.9,您可以使用NSCalendars

    - (BOOL)isDate:(NSDate *)date1 equalToDate:(NSDate *)date2 toUnitGranularity:(NSCalendarUnit)unit;
    
  • 53

    在Swift 3.0,iOS8中

    if NSCalendar.current.isDate(Date(), equalTo: date, toGranularity: .day) {
    
    }
    

    要么

    if NSCalendar.current.isDateInToday(date) {
    
    }
    
  • -1

    我创建自己的实用程序类 .

    ZYUtility.h

    @interface ZYUtility : NSObject
    + (NSDate *)yesterday;
    + (NSDate *)tomorrow;
    + (NSDate *)endOfDay:(NSDate *)date;
    + (NSDate *)beginningOfDay:(NSDate *)date;
    @end
    

    ZYUtility.m

    + (NSDate *)yesterday;
    {
        NSCalendar *calendar = [NSCalendar currentCalendar];
        NSDateComponents *componets = [calendar components:NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit
                                                  fromDate:[NSDate date]];
        componets.day -= 1;
        componets.hour = 24;
        componets.minute = 0;
        componets.second = 0;
    
        return [calendar dateFromComponents:componets];
    }
    
    + (NSDate *)tomorrow;
    {
        NSCalendar *calendar = [NSCalendar currentCalendar];
        NSDateComponents *componets = [calendar components:NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit
                                                  fromDate:[NSDate date]];
        componets.day += 1;
        componets.hour = 0;
        componets.minute = 0;
        componets.second = 0;
    
        return [calendar dateFromComponents:componets];
    }
    
    + (NSDate *)beginningOfDay:(NSDate *)date {
        NSCalendar *calendar = [NSCalendar currentCalendar];
    
        unsigned unitFlags = NSYearCalendarUnit | NSMonthCalendarUnit |  NSDayCalendarUnit;
        NSDateComponents *comp = [calendar components:unitFlags fromDate:date];
    
        return [calendar dateFromComponents:comp];
    }
    
    + (NSDate *)endOfDay:(NSDate *)date {
        NSCalendar *calendar = [NSCalendar currentCalendar];
    
        NSDateComponents *components = [NSDateComponents new];
        components.day = 1;
    
        NSDate *theDate = [calendar dateByAddingComponents:components
                                                    toDate:[ZYUtility beginningOfDay:date]
                                                   options:0];
    
        theDate = [theDate dateByAddingTimeInterval:-1];
    
        return theDate;
    }
    
  • -1

    以下将测试两个日期是否代表给定时代的同一天(在许多情况下这是足够的):

    - (BOOL)isDate:(NSDate *)date1 sameDayAsDate:(NSDate *)date2 {
        NSCalendar *calendar = [NSCalendar currentCalendar];
        int diff = [calendar ordinalityOfUnit:NSDayCalendarUnit 
                                       inUnit:NSEraCalendarUnit 
                                      forDate:date1] -
                   [calendar ordinalityOfUnit:NSDayCalendarUnit 
                                       inUnit:NSEraCalendarUnit 
                                      forDate:date2];
        return 0 == diff;
    }
    

相关问题