ios - swift time class




2 개의 NSDate 사이의 일 수 (11)

이 질문에는 이미 답변이 있습니다.

NSDate 값 사이의 일 수를 어떻게 결정할 수 있습니까?

NSDate 값은 [NSDate date] 형식의 형식입니다.

특히 사용자가 내 iPhone 앱에 비활성 상태로 들어가면 다음 값을 저장합니다.

exitDate = [NSDate date];

앱을 다시 열면 현재 시간이 표시됩니다.

NSDate *now = [NSDate date];

이제 다음을 구현하고 싶습니다.

-(int)numberOfDaysBetweenStartDate:exitDate andEndDate:now

@ 브라이언

Brian의 답변은 좋지만 24 시간 청크의 경우 일별 차이 만 계산하지만 달력의 일일 차이는 계산하지 않습니다. 예를 들어, 12 월 24 일 23시 59 분은 성탄일 (Christmas Day)에서 불과 1 분 거리에 있습니다. Brian의 daysBetween 함수는 0을 반환합니다.

Brian의 원래 구현과 시작 / 끝에서 빌려 내 프로그램에서 다음을 사용합니다. ( NSDate 시작일과 종료일 )

- (NSDate *)beginningOfDay:(NSDate *)date
{
    NSCalendar *cal = [NSCalendar currentCalendar];
    NSDateComponents *components = [cal components:( NSDayCalendarUnit | NSMonthCalendarUnit | NSYearCalendarUnit | NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit ) fromDate:date];
    [components setHour:0];
    [components setMinute:0];
    [components setSecond:0];
    return [cal dateFromComponents:components];
}

- (NSDate *)endOfDay:(NSDate *)date
{
    NSCalendar *cal = [NSCalendar currentCalendar];
    NSDateComponents *components = [cal components:( NSDayCalendarUnit | NSMonthCalendarUnit | NSYearCalendarUnit | NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit ) fromDate:date];
    [components setHour:23];
    [components setMinute:59];
    [components setSecond:59];
    return [cal dateFromComponents:components];
}

- (int)daysBetween:(NSDate *)date1 and:(NSDate *)date2 {
    NSDate *beginningOfDate1 = [self beginningOfDay:date1];
    NSDate *endOfDate1 = [self endOfDay:date1];
    NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
    NSDateComponents *beginningDayDiff = [calendar components:NSDayCalendarUnit fromDate:beginningOfDate1 toDate:date2 options:0];
    NSDateComponents *endDayDiff = [calendar components:NSDayCalendarUnit fromDate:endOfDate1 toDate:date2 options:0];
    if (beginningDayDiff.day > 0)
        return beginningDayDiff.day;
    else if (endDayDiff.day < 0)
        return endDayDiff.day;
    else {
        return 0;
    }
}

Swift에서 Brian의 기능 구현은 다음과 같습니다.

class func daysBetweenThisDate(fromDateTime:NSDate, andThisDate toDateTime:NSDate)->Int?{

    var fromDate:NSDate? = nil
    var toDate:NSDate? = nil

    let calendar = NSCalendar.currentCalendar()

    calendar.rangeOfUnit(NSCalendarUnit.DayCalendarUnit, startDate: &fromDate, interval: nil, forDate: fromDateTime)

    calendar.rangeOfUnit(NSCalendarUnit.DayCalendarUnit, startDate: &toDate, interval: nil, forDate: toDateTime)

    if let from = fromDate {

        if let to = toDate {

            let difference = calendar.components(NSCalendarUnit.DayCalendarUnit, fromDate: from, toDate: to, options: NSCalendarOptions.allZeros)

            return difference.day
        }
    }

    return nil
}

나는 시작일을 포함하여 두 날짜 사이의 일수가 필요했다. 예 : 14-2-2012 및 16-2-2012 사이의 날짜는 3의 결과를 생성합니다.

+ (NSInteger)daysBetween:(NSDate *)dt1 and:(NSDate *)dt2 {
        NSUInteger unitFlags = NSDayCalendarUnit;
        NSCalendar* calendar = [NSCalendar currentCalendar];
        NSDateComponents *components = [calendar components:unitFlags fromDate:dt1 toDate:dt2 options:0];
        NSInteger daysBetween = abs([components day]);
    return daysBetween+1;
}

날짜를 제공하는 순서는 중요하지 않습니다. 항상 양수를 반환합니다.


나는 이것을 NSDate 클래스의 카테고리 메소드로 사용한다.

// returns number of days (absolute value) from another date (as number of midnights beween these dates)
- (int)daysFromDate:(NSDate *)pDate {
    NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
    NSInteger startDay=[calendar ordinalityOfUnit:NSCalendarUnitDay
                                           inUnit:NSCalendarUnitEra
                                          forDate:[NSDate date]];
    NSInteger endDay=[calendar ordinalityOfUnit:NSCalendarUnitDay
                                         inUnit:NSCalendarUnitEra
                                        forDate:pDate];
    return abs(endDay-startDay);
}

내가 찾은 해결책은 다음과 같습니다.

+(NSInteger)getDaysDifferenceBetween:(NSDate *)dateA and:(NSDate *)dateB {

  if ([dateA isEqualToDate:dateB]) 
    return 0;

  NSCalendar * gregorian = 
        [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];



  NSDate * dateToRound = [dateA earlierDate:dateB];
  int flags = (NSYearCalendarUnit | NSMonthCalendarUnit |  NSDayCalendarUnit);
  NSDateComponents * dateComponents = 
         [gregorian components:flags fromDate:dateToRound];


  NSDate * roundedDate = [gregorian dateFromComponents:dateComponents];

  NSDate * otherDate = (dateToRound == dateA) ? dateB : dateA ;

  NSInteger diff = abs([roundedDate timeIntervalSinceDate:otherDate]);

  NSInteger daysDifference = floor(diff/(24 * 60 * 60));

  return daysDifference;
}

여기서는 요나단이 위에서 제안한 것처럼 첫날을 효과적으로 시작하여 그 차이를 계산합니다.


다음은 두 날짜 사이의 달력 일 수를 결정하기 위해 사용한 구현입니다.

+ (NSInteger)daysBetweenDate:(NSDate*)fromDateTime andDate:(NSDate*)toDateTime
{
    NSDate *fromDate;
    NSDate *toDate;

    NSCalendar *calendar = [NSCalendar currentCalendar];

    [calendar rangeOfUnit:NSCalendarUnitDay startDate:&fromDate
        interval:NULL forDate:fromDateTime];
    [calendar rangeOfUnit:NSCalendarUnitDay startDate:&toDate
        interval:NULL forDate:toDateTime];

    NSDateComponents *difference = [calendar components:NSCalendarUnitDay
        fromDate:fromDate toDate:toDate options:0];

    return [difference day];
}

편집하다:

위의 환상적인 솔루션은 아래 NSDate 의 확장판 인 Swift 버전입니다.

extension NSDate {
  func numberOfDaysUntilDateTime(toDateTime: NSDate, inTimeZone timeZone: NSTimeZone? = nil) -> Int {
    let calendar = NSCalendar.currentCalendar()
    if let timeZone = timeZone {
      calendar.timeZone = timeZone
    }

    var fromDate: NSDate?, toDate: NSDate?

    calendar.rangeOfUnit(.Day, startDate: &fromDate, interval: nil, forDate: self)
    calendar.rangeOfUnit(.Day, startDate: &toDate, interval: nil, forDate: toDateTime)

    let difference = calendar.components(.Day, fromDate: fromDate!, toDate: toDate!, options: [])
    return difference.day
  }
}

유스 케이스에 따라 제거 할 수있는 약간의 언 래핑 랩핑.

위의 해결 방법은 현재 시간대가 아닌 다른 시간대에서도 작동하며 전 세계 장소에 대한 정보를 보여주는 앱에 가장 적합합니다.


또 다른 접근법 :

NSDateFormatter* dayFmt = [[NSDateFormatter alloc] init];
[dayFmt setTimeZone:<whatever time zone you want>];
[dayFmt setDateFormat:@"g"];
NSInteger firstDay = [[dayFmt stringFromDate:firstDate] integerValue];    
NSInteger secondDay = [[dayFmt stringFromDate:secondDate] integerValue];
NSInteger difference = secondDay - firstDay;

시간대를 고려할 수있는 timeIntervalSince... 스키마보다 이점이 있으며 단 몇 초 또는 하루 동안 긴 간격으로 모호성이 없습니다.

그리고 NSDateComponents가 접근하는 것보다 조금 더 작고 혼란스럽지 않습니다.


여기에 내가 찾은 최고의 해결책이있다. NSDates간에 단위를 결정하는 Apple의 승인 된 방법을 활용하는 것 같습니다.

- (int)daysBetween:(NSDate *)dt1 and:(NSDate *)dt2 {
    NSUInteger unitFlags = NSDayCalendarUnit;
    NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar]; 
    NSDateComponents *components = [calendar components:unitFlags fromDate:dt1 toDate:dt2 options:0];
    return [components day]+1;
}

예를 들어 월을 원한다면 'NSMonthCalendarUnit'을 unitFlag로 포함 할 수 있습니다.

원본 블로거를 신용하기 위해, 나는이 정보를 여기에서 발견했다. (비록 내가 위에 고친 약간의 실수가 있었지만) : http://cocoamatic.blogspot.com/2010/09/nsdate-number-of-days-between-two-dates.html?showComment=1306198273659#c6501446329564880344


왜 아닙니다 :

int days = [date1 timeIntervalSinceDate:date2]/24/60/60;

하나, 정확히 당신이 원하는지 모르겠지만, 그것은 당신을 도울 수있는, (날 도와 줘 !!)

내 목표는 두 개의 날짜 (24 시간 미만 차이) 사이에 "overday"요일 + 1 :

나는 다음과 같이했다 (나는 조금은 고대이다).

NSDate *startDate = ...
NSDate *endDate = ...

다른 NSDateFormatter에 의해 이미 포맷 된 NSDate (이것은 단지이 목적을위한 것입니다 :)

NSDateFormatter *dayFormater = [[NSDateFormatter alloc]init];
[dayFormater setDateFormat:@"dd"];

int startDateDay = [[dayFormater stringFromDate:startDate]intValue];

int endDateDay = [[dayFormater stringFromDate:dateOn]intValue];

if (endDateDay > startDateDay) {
    NSLog(@"day+1");
} else {
    NSLog(@"same day");
}

어쩌면 이것과 같은 것이 이미 존재하지만 그것을 찾지 못했을 것입니다.


NSDate *lastDate = [NSDate date];
NSDate *todaysDate = [NSDate date];
NSTimeInterval lastDiff = [lastDate timeIntervalSinceNow];
NSTimeInterval todaysDiff = [todaysDate timeIntervalSinceNow];
NSTimeInterval dateDiff = lastDiff - todaysDiff;

dateDiff는 두 날짜 사이의 초 수입니다. 하루에 초 수로 나누십시오.







nsdate