web-dev-qa-db-ja.com

Cocoa-Touch:2つのNSDateが同じ日にあるかどうかを確認するにはどうすればよいですか?

2つのNSDateインスタンスが両方とも同じ日付のものであるかどうかを知る必要があります。

NSDateComponentsを取得して日/月/年を比較するよりも簡単で良い方法はありますか?

67
Prody

NSDateComponentsは私にとって最善の策のように聞こえます。もう1つの方法は、CFDateにフリーダイヤルしてからCFDateGetAbsoluteTimeを使用して、2つの日付間の時間を取得するために減算を行うことです。ただし、時差が同じ日に日付を取得するかどうかを計算するには、いくつかの追加の計算を行う必要があります。

7
fbrereto

iOS 8(およびOS X 10.9)以降をターゲットにしている場合Joe's answer は新しいこの目的のためだけのNSCalendarのメソッド:

-[NSCalendar isDate:inSameDayAsDate:]

iOS 7以前の場合: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];
}
154
progrmr

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の一部です。

53
Joe Masilotti

(注:iOS 8以降でこれを行うための良い方法については、ジョーの回答を参照してください)

私は日付フォーマッターを使用しています:

NSDateFormatter *dateComparisonFormatter = [[[NSDateFormatter alloc] init] autorelease];
[dateComparisonFormatter setDateFormat:@"yyyy-MM-dd"];

if( [[dateComparisonFormatter stringFromDate:firstDate] isEqualToString:[dateComparisonFormatter stringFromDate:secondDate]] ) {
    …
}

HTH。

24
Ben Lachman

Swiftの場合:

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

彼らが同じ日にいる場合はtrueを返します。

13
vikzilla

私は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...
}
11
aapierce

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];
}
5
Bruce Geerdes
NSCalendar.currentCalendar().isDateInToday(yourNSDate)

IOS 8.0以降およびOS X v10.9以降で利用できます。

4
philipp

Swift 3.0、iOS8 +

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

}

または

if NSCalendar.current.isDateInToday(date) {

}
1
norbDEV

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;
1
vikingosegundo