Раунд NSDate до ближайших 5 минут - PullRequest
53 голосов
/ 19 июля 2009

Например, у меня есть

NSDate *curDate = [NSDate date];

и его значение 9:13 утра. Я не использую год, месяц и день в curDate.

То, что я хочу получить, это дата со значением времени 9:15; Если у меня есть значение времени 9:16, я хочу увеличить его до 9:20 и т. Д.

Как я могу сделать это с NSDate?

Ответы [ 18 ]

2 голосов
/ 30 апреля 2015

Еще одно универсальное решение Swift, которое работает с округлением до 30 минут с использованием NSCalendar

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!;
    }
}
1 голос
/ 19 октября 2014

Я переписал решение @ J3RM как расширение в Swift для класса NSDate. Вот для округления даты до ближайшего 15-минутного интервала:

extension NSDate
{
    func nearestFifteenthMinute() -> NSDate!
    {
        let referenceTimeInterval = Int(self.timeIntervalSinceReferenceDate)
        let remainingSeconds = referenceTimeInterval % 900
        var timeRoundedTo5Minutes = referenceTimeInterval - remainingSeconds
        if remainingSeconds > 450
        {
            timeRoundedTo5Minutes = referenceTimeInterval + (900 - remainingSeconds)
        }
        let roundedDate = NSDate.dateWithTimeIntervalSinceReferenceDate(NSTimeInterval(timeRoundedTo5Minutes))
        return roundedDate
    }
}
1 голос
/ 24 декабря 2014

Я знаю, что это более старая тема, но поскольку есть более свежие ответы, я поделюсь вспомогательным методом, который я использую для округления NSDate до ближайшего 5-минутного интервала.

Я использую это для заполнения UITextField текущей датой UIDatePicker, когда она становится FirstResponder. Вы не можете просто использовать [NSDate date], когда UIDatePicker настроен с чем-то отличным от 1-минутного интервала. Мои настроены с 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];
1 голос
/ 21 июля 2009

Я искал это сам, но использование приведенного выше примера дало мне даты 0001 года.

Вот мой вариант, включенный в более элегантное модное предложение smorgan, но будьте осторожны, я еще не проверил это на утечку:

NSDate *myDate = [NSDate date];
// Get the nearest 5 minute block
NSDateComponents *time = [[NSCalendar currentCalendar] components:NSHourCalendarUnit | NSMinuteCalendarUnit
                                                         fromDate:myDate];
NSInteger minutes = [time minute];
int remain = minutes % 5;
// Add the remainder of time to the date to round it up evenly
myDate = [myDate addTimeInterval:60*(5-remain)];
0 голосов
/ 18 августа 2017

Еще короче ... предел в секундах:

let seconds = ceil(Date().timeIntervalSinceReferenceDate/300.0)*300.0
let roundedDate = Date(timeIntervalSinceReferenceDate: seconds)
0 голосов
/ 03 сентября 2011

Я не уверен, насколько эффективны 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;
}
0 голосов
/ 20 июля 2015
- (NSDate *)roundDateToNearestFiveMinutes:(NSDate *)date
{
    NSDateComponents *time = [[NSCalendar currentCalendar]
                              components:NSHourCalendarUnit | NSMinuteCalendarUnit
                              fromDate:date];
    NSInteger minutes = [time minute];
    float minuteUnit = ceil((float) minutes / 5.0);
    minutes = minuteUnit * 5.0;
    [time setMinute: minutes];
    return [[NSCalendar currentCalendar] dateFromComponents:time];
}
0 голосов
/ 13 марта 2015

Это общее решение, которое округляет до ближайшего значения '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];
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...