iphone - swift datecomponents 현재



NSDate를 가장 가까운 5 분으로 반올림합니다. (12)

Chris '와 swift3을 기반으로 한이 방법은 어떨까요?

import UIKit

enum DateRoundingType {
    case round
    case ceil
    case floor
}

extension Date {
    func rounded(minutes: TimeInterval, rounding: DateRoundingType = .round) -> Date {
        return rounded(seconds: minutes * 60, rounding: rounding)
    }
    func rounded(seconds: TimeInterval, rounding: DateRoundingType = .round) -> Date {
        var roundedInterval: TimeInterval = 0
        switch rounding  {
        case .round:
            roundedInterval = (timeIntervalSinceReferenceDate / seconds).rounded() * seconds
        case .ceil:
            roundedInterval = ceil(timeIntervalSinceReferenceDate / seconds) * seconds
        case .floor:
            roundedInterval = floor(timeIntervalSinceReferenceDate / seconds) * seconds
        }
        return Date(timeIntervalSinceReferenceDate: roundedInterval)
    }
}

// Example

let nextFiveMinuteIntervalDate = Date().rounded(minutes: 5, rounding: .ceil)
print(nextFiveMinuteIntervalDate)

https://ffff65535.com

예를 들면 나는 가지고있다.

NSDate *curDate = [NSDate date];

그 값은 오전 9시 13 분입니다. 나는 curDate의 년, 월, 일 부분을 사용하지 않습니다.

내가 원하는 것은 9시 15 분의 시간 값을 가진 날짜입니다. 시간 값이 9시 16 분이면 9시 20 분까지 진행하고 싶습니다.

NSDate로 어떻게 할 수 있습니까?


NSCalendar를 사용하여 최대 30 분 동안 반올림하는 신속한 일반 솔루션 1 개

extension NSDate {
    func nearest(minutes: Int) -> NSDate {
        assert(minutes <= 30, "nearest(m) suppport rounding up to 30 minutes");
        let cal = NSCalendar.currentCalendar();
        var time = cal.components(.CalendarUnitMinute | .CalendarUnitSecond, fromDate: self);
        let rem = time.minute % minutes
        if rem > 0 {
            time.minute = minutes - rem;
        }
        time.second = -time.second;
        time.nanosecond = -time.nanosecond //updated 7.07.15
        let date = cal.dateByAddingComponents(time, toDate: self, options: NSCalendarOptions(0));
        return date!;
    }
}

NSDateComponents가 얼마나 효율적인 지 확신 할 수 없지만, NSDate 자체를 다루고 싶다면 조작 할 수있는 초 단위의 값을 줄 수 있습니다.

예를 들어,이 메서드는 가장 가까운 분으로 내림합니다. 60을 300으로 변경하면 가장 가까운 5 분으로 반올림됩니다.

+ (NSDate *)dateRoundedDownToMinutes:(NSDate *)date {
    // Strip miliseconds by converting to int
    int referenceTimeInterval = (int)[date timeIntervalSinceReferenceDate];

    int remainingSeconds = referenceTimeInterval % 60;
    int timeRoundedDownToMinutes = referenceTimeInterval - remainingSeconds;

    NSDate *roundedDownDate = [NSDate dateWithTimeIntervalSinceReferenceDate:(NSTimeInterval)timeRoundedDownToMinutes];

    return roundedDownDate;
}

Wowsers, 여기에 많은 답변이 있지만 많은 사람들이 이해하기가 길거나 이해하기 힘들 기 때문에 도움이 될 수 있도록 2 센트를 던지려고합니다. NSCalendar 클래스는 필요한 기능을 안전하고 간결하게 제공합니다. 다음은 시간 간격 초, 반올림 또는 기타를 곱하지 않고 나를 위해 작동하는 솔루션입니다. NSCalendar 는 윤년 / 일 및 기타 시간 및 날짜 기이를 고려합니다. (Swift 2.2)

let calendar = NSCalendar.currentCalendar()
let rightNow = NSDate()
let interval = 15
let nextDiff = interval - calendar.component(.Minute, fromDate: rightNow) % interval
let nextDate = calendar.dateByAddingUnit(.Minute, value: nextDiff, toDate: rightNow, options: []) ?? NSDate()

필요한 경우 NSDate 의 확장에 추가하거나 새로운 NSDate 인스턴스를 반환하는 자유 형식의 함수로 필요할 때마다 추가 할 수 있습니다. 희망이 그것을 필요로하는 사람.

스위프트 3 업데이트

let calendar = Calendar.current  
let rightNow = Date()  
let interval = 15  
let nextDiff = interval - calendar.component(.minute, from: rightNow) % interval  
let nextDate = calendar.date(byAdding: .minute, value: nextDiff, to: rightNow) ?? Date()

나는 이것이 더 오래된 쓰레드라는 것을 알고있다. 그러나 더 최근의 답이 있기 때문에 NSDate를 가장 가까운 5 분 간격으로 반올림하는 유틸리티 메소드를 공유 할 것이다.

FirstResponder가 될 때 이것을 사용하여 UITextField를 현재 UIDatePicker 날짜로 채 웁니다. UIDatePicker가 1 분 간격 이외의 다른 것으로 구성된 경우 [NSDate date]를 사용할 수 없습니다. 광산은 5 분 간격으로 구성됩니다.

+ (NSDate *)roundToNearest5MinuteInterval {

    NSDate *ceilingDate = [NSDate dateWithTimeIntervalSinceReferenceDate:ceil([[NSDate date] timeIntervalSinceReferenceDate]/300.0)*300.0];
    NSDate *floorDate = [NSDate dateWithTimeIntervalSinceReferenceDate:floor([[NSDate date] timeIntervalSinceReferenceDate]/300.0)*300.0];
    NSTimeInterval ceilingInterval = [ceilingDate timeIntervalSinceNow];
    NSTimeInterval floorInterval = [floorDate timeIntervalSinceNow];

    if (fabs(ceilingInterval) < fabs(floorInterval)) {
        return ceilingDate;
    } else {
        return floorDate;
    }
}

질문의 제목을 무시하고 @aler가 실제로 달성하고자하는 것을 읽습니다 (가장 가까운 5 분으로 올림). 당신이해야 할 일은 다음과 같습니다 :

NSDate *ceilingDate = [NSDate dateWithTimeIntervalSinceReferenceDate:ceil([[NSDate date] timeIntervalSinceReferenceDate]/300.0)*300.0];

나는 이것이 최선의 해결책이라고 생각하지만, 이전의 포스터 코드에 기초한 제 의견입니다. 가장 가까운 5 분 표시로 반올림됩니다. 이 코드는 날짜 구성 요소 솔루션보다 훨씬 적은 메모리를 사용해야합니다. 훌륭해, 방향에 고마워.

+(NSDate *) dateRoundedDownTo5Minutes:(NSDate *)dt{
    int referenceTimeInterval = (int)[dt timeIntervalSinceReferenceDate];
    int remainingSeconds = referenceTimeInterval % 300;
    int timeRoundedTo5Minutes = referenceTimeInterval - remainingSeconds; 
    if(remainingSeconds>150)
    {/// round up
         timeRoundedTo5Minutes = referenceTimeInterval +(300-remainingSeconds);            
    }
    NSDate *roundedDate = [NSDate dateWithTimeIntervalSinceReferenceDate:(NSTimeInterval)timeRoundedTo5Minutes];
    return roundedDate;
}

방금 내 응용 프로그램을 위해 이것을 실험하기 시작했고, 다음을 생각해 냈습니다. 그것은 Swift에 있지만 Swift를 모르는 경우에도 충분히 이해할 수 있어야합니다.

func skipToNextEvenFiveMinutesFromDate(date: NSDate) -> NSDate {
   var componentMask : NSCalendarUnit = (NSCalendarUnit.CalendarUnitYear | NSCalendarUnit.CalendarUnitMonth | NSCalendarUnit.CalendarUnitDay | NSCalendarUnit.CalendarUnitHour | NSCalendarUnit.CalendarUnitMinute)
   var components = NSCalendar.currentCalendar().components(componentMask, fromDate: date)

   components.minute += 5 - components.minute % 5
   components.second = 0
   if (components.minute == 0) {
      components.hour += 1
   }

   return NSCalendar.currentCalendar().dateFromComponents(components)!
}

내 놀이터에서 올바른 결과를 얻었는데, 여기에서 자정에 가까운 다양한 맞춤식 날짜를 삽입하고 새해와 가까워집니다.

편집 : Swift2 지원 :

 func skipToNextEvenFiveMinutesFromDate(date: NSDate) -> NSDate {
    let componentMask : NSCalendarUnit = ([NSCalendarUnit.Year , NSCalendarUnit.Month , NSCalendarUnit.Day , NSCalendarUnit.Hour ,NSCalendarUnit.Minute])
    let components = NSCalendar.currentCalendar().components(componentMask, fromDate: date)

    components.minute += 5 - components.minute % 5
    components.second = 0
    if (components.minute == 0) {
        components.hour += 1
    }

    return NSCalendar.currentCalendar().dateFromComponents(components)!
}

분 값을 취하고 5로 반올림하여 다음 5 분 단위로 나누고 5를 곱하여이를 다시 분으로 가져오고 새 NSDate를 만듭니다.

NSDateComponents *time = [[NSCalendar currentCalendar]
                          components:NSHourCalendarUnit | NSMinuteCalendarUnit
                            fromDate:curDate];
NSInteger minutes = [time minute];
float minuteUnit = ceil((float) minutes / 5.0);
minutes = minuteUnit * 5.0;
[time setMinute: minutes];
curDate = [[NSCalendar currentCalendar] dateFromComponents:time];

샘플 주셔서 감사합니다. 아래에서 가장 가까운 5 분에 몇 가지 코드를 추가했습니다.

 -(NSDate *)roundDateTo5Minutes:(NSDate *)mydate{
    // Get the nearest 5 minute block
    NSDateComponents *time = [[NSCalendar currentCalendar]
                              components:NSHourCalendarUnit | NSMinuteCalendarUnit
                              fromDate:mydate];
    NSInteger minutes = [time minute];
    int remain = minutes % 5;
    // if less then 3 then round down
    if (remain<3){
        // Subtract the remainder of time to the date to round it down evenly
        mydate = [mydate addTimeInterval:-60*(remain)];
    }else{
        // Add the remainder of time to the date to round it up evenly
        mydate = [mydate addTimeInterval:60*(5-remain)];
    }
    return mydate;
}

심지어 더 짧은 ... 초까지 제한 :

let seconds = ceil(Date().timeIntervalSinceReferenceDate/300.0)*300.0
let roundedDate = Date(timeIntervalSinceReferenceDate: seconds)

이것은 가장 가까운 입력 'mins'에 올림하는 일반적인 솔루션입니다 :

+(NSDate *)roundUpDate:(NSDate *)aDate toNearestMins:(NSInteger)mins
{
    NSDateComponents *components = [[NSCalendar currentCalendar] components:NSUIntegerMax fromDate:aDate];

    NSInteger dateMins = components.minute;
    dateMins = ((dateMins+mins)/mins)*mins;

    [components setMinute:dateMins];
    [components setSecond:0];
    return [[NSCalendar currentCalendar] dateFromComponents:components];
}

https://forums.developer.apple.com/thread/92399

Apple 직원의 전체 답변과 상세한 답변을 보려면 링크를 참조하십시오. 클릭 한 번으로 저장하려면 다음을 수행하십시오.

let original = Date()

let rounded = Date(timeIntervalSinceReferenceDate: 
(original.timeIntervalSinceReferenceDate / 300.0).rounded(.toNearestOrEven) * 300.0)




cocoa