code

Cocoa-Touch : 두 개의 NSDates가 같은 날에 있는지 어떻게 알 수 있습니까?

codestyles 2020. 11. 9. 08:11
반응형

Cocoa-Touch : 두 개의 NSDates가 같은 날에 있는지 어떻게 알 수 있습니까?


두 개의 NSDate 인스턴스가 모두 같은 날에 있는지 알아야합니다.

NSDateComponents를 얻고 일 / 월 / 년을 비교하는 것보다 더 쉽고 / 더 나은 방법이 있습니까?


NSDateComponents는 나에게 가장 좋은 방법 인 것 같습니다. 시도 할 또 다른 방법은 수신자 부담으로 CFDate에 연결 한 다음 CFDateGetAbsoluteTime을 사용하고 빼기를 수행하여 두 날짜 사이의 시간을 구하는 것입니다. 그러나 시차가 같은 날 날짜에 도달하는지 알아 내기 위해 몇 가지 추가 계산을 수행해야합니다.


타겟팅하는 경우 아이폰 OS 8 (그리고 OS X 10.9) 이상을 , 다음 조의 대답은 바로이 목적을 위해 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];
}

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의 일부입니다.


(참고 : iOS 8 이상에서이를 수행하는 좋은 방법은 Joe의 답변을 참조하십시오.)

날짜 포맷터를 사용합니다.

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

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

HTH.


Swift에서 :

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

같은 날이면 true를 반환합니다.


나는 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...
}

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];
}

NSCalendar.currentCalendar().isDateInToday(yourNSDate)

iOS 8.0 이상 및 OS X v10.9 이상에서 사용할 수 있습니다.


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;

Swift 3.0, iOS8 +

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

}

또는

if NSCalendar.current.isDateInToday(date) {

}

나만의 유틸리티 클래스를 만듭니다.

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;
}

다음은 두 날짜가 주어진 시대에서 같은 날을 나타내는 지 테스트합니다 (대부분의 경우 충분 함).

- (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;
}

참고URL : https://stackoverflow.com/questions/1561554/cocoa-touch-how-do-i-see-if-two-nsdates-are-in-the-same-day

반응형