Eugene Brusov
Eugene Brusov

Reputation: 17846

swift 3 getting list of nearest hour quarters

Okay, I have let date = Date() in Swift 3 and I need to get list of nearest hour quarters.

Let's say current date is 2017-02-08 15:24:56 +0000 so that desired list will be

2017-02-08 15:30:00 +0000
2017-02-08 15:45:00 +0000
2017-02-08 16:00:00 +0000

How can I get that list of Date?

EDIT 1 2/8/2017 5:54 PM

Here is what I just tried to do and looks like it get results I need.

    let currentDate = Date()
    var minute = Calendar.current.component(.minute, from: currentDate)

    if minute < 15 {
        minute = 15
    } else if minute < 30 {
        minute = 30
    } else if minute < 45 {
        minute = 45
    } else {
        minute = 0
    }

    var hourQuarterDate = Calendar.current.nextDate(after: currentDate, matching: DateComponents(minute: minute), matchingPolicy: .strict, repeatedTimePolicy: .first, direction: .forward)!

    var hourQuarters = [Date]()
    hourQuarters.append(hourQuarterDate)

    for _ in 1...10 {
        hourQuarterDate = Calendar.current.date(byAdding: .minute, value: 15, to: hourQuarterDate)!
        hourQuarters.append(hourQuarterDate)
    }

Upvotes: 3

Views: 2374

Answers (4)

sereisoglu
sereisoglu

Reputation: 53

I like the solution here and I edited it into an extension to find the nearest quarter-hour.

extension Date {
    func nearestQuarterHourToTheFuture() -> Date {
        let granularity = 900.0 // 60.0 * 15.0
        
        return Date(timeIntervalSinceReferenceDate: (self.timeIntervalSinceReferenceDate / granularity).rounded(.up) * granularity)
    }
}

print(Date().nearestQuarterHourToTheFuture())

Upvotes: 1

Brian Bird
Brian Bird

Reputation: 1206

My Refactored Solution tested with swift 4 Xcode 12

extension Date {
func roundUp(totalMinutes: Int) -> Int
{
  for index in 1...3 {
    if (totalMinutes < index * 15) {return index * 15}
  }
  return 60
}
func nextFifteenMinutes() -> Date
{
   let cal = Calendar.current
   let minutes = cal.component(.minute, from: self)
   let roundedMinute = roundUp(totalMinutes: minutes)
   
   return cal.date(byAdding: .minute, value: roundedMinute - minutes, to: self)!
}}

usage:

Date().nextFifteenMinutes()

Upvotes: 1

Marco Di Fiore
Marco Di Fiore

Reputation: 31

extension Date {
func nextFifteenMinutes() -> Date
{
    let cal = Calendar.current
    let minutes = cal.component(.minute, from: self)
    var roundedMinute = minutes
    if minutes < 15 {
        roundedMinute = 15
    } else if minutes < 30 {
        roundedMinute = 30
    } else if minutes < 45 {
        roundedMinute = 45
    } else {
        roundedMinute = 60
    }
    return cal.date(byAdding: .minute, value: roundedMinute - minutes, to: self)!
}}

usage:

 Date().nextFifteenMinutes()

Upvotes: 2

Noyer282
Noyer282

Reputation: 984

Your edit was helpful. Here's a slight variation I implemented based on it.

My main step is to round the current date down to the latest quarter of an hour:

// Parameters
let minuteGranuity = 15
let numberOfDates = 4

// Find current date and date components
let now = Date()                                   
//2017-03-06 13:23:40 +0000
let calendar = Calendar.current
let hour = calendar.component(.hour, from: now)
let minute = calendar.component(.minute, from: now)

// Round down to nearest date:
let floorMinute = minute - (minute % minuteGranuity)
let floorDate = calendar.date(bySettingHour: hour, 
                              minute: floorMinute, 
                              second: 0, 
                              of: now)!

As in your edit, I use the "date(byAdding: " method to add 15 minute intervals to that base date:

var dates: [Date] = []
for minutes in stride(from: minuteGranuity, through: minuteGranuity*numberOfDates, by: minuteGranuity) {
    let newDate = calendar.date(byAdding: .minute, value: minutes, to: floorDate)!
    dates.append(newDate)
}

for date in dates {
    print(date)
}

// 2017-03-06 13:30:00 +0000
// 2017-03-06 13:45:00 +0000
// 2017-03-06 14:00:00 +0000
// 2017-03-06 14:15:00 +0000

Upvotes: 6

Related Questions