Получить диапазоны недель на основе даты начала и количества заданных недель - PullRequest
0 голосов
/ 12 июля 2020

У меня есть дата начала 13 июля 2020 года и Int, представляющий количество недель, которые я выбрал, в данном случае пять. Я хотел бы напечатать каждую неделю за эти пять недель. Пример ожидаемого результата:

  1. 13 июля - 19 июля
  2. 20 июля - 26 июля
  3. 27 июля - 2 августа
  4. 3 августа - 9 августа
  5. 10 августа - 16 августа

С помощью приведенного ниже кода я могу получить первые две недели, однако недели должны продолжать печататься в зависимости от ввода недель.

func getRanges() {
    let arrWeekDates = rangeString!.getWeekDates() // Get dates of two weeks.
    let dateFormat = "MMM dd"
    let thisMon = arrWeekDates.thisWeek.first!.toDate(format: dateFormat)
    let thisSun = arrWeekDates.thisWeek[arrWeekDates.thisWeek.count - 1].toDate(format: dateFormat)

    let nextMon = arrWeekDates.nextWeek.first!.toDate(format: dateFormat)
    let nextSun = arrWeekDates.nextWeek[arrWeekDates.nextWeek.count - 1].toDate(format: dateFormat)

    print("This Week: \(thisMon) - \(thisSun)")
    print("Next Week: \(nextMon) - \(nextSun)")
    
}

extension Date {

func getWeekDates() -> (thisWeek:[Date],nextWeek:[Date]) {
        var tuple: (thisWeek:[Date],nextWeek:[Date])
        var arrThisWeek: [Date] = []
        for i in 0..<7 {
            arrThisWeek.append(Calendar.current.date(byAdding: .day, value: i, to: startOfWeek)!)
        }
        var arrNextWeek: [Date] = []
        for i in 1...7 {
            arrNextWeek.append(Calendar.current.date(byAdding: .day, value: i, to: arrThisWeek.last!)!)
        }
        tuple = (thisWeek: arrThisWeek,nextWeek: arrNextWeek)
        return tuple
    }

var startOfWeek: Date {
            let gregorian = Calendar(identifier: .gregorian)
            let sunday = gregorian.date(from: gregorian.dateComponents([.yearForWeekOfYear, .weekOfYear], from: self))
            return gregorian.date(byAdding: .day, value: 1, to: sunday!)!
        }
func toDate(format: String) -> String {
        let formatter = DateFormatter()
        formatter.dateFormat = format
        return formatter.string(from: self)
    }
   }

1 Ответ

0 голосов
/ 13 июля 2020

Я создал функцию, которая принимает в качестве аргументов дату начала и количество недель и возвращает массив DateInterval для дат начала и окончания недели

func weeks(from date: Date, duration: Int) -> [DateInterval]? {
    let calendar = Calendar.current

    //Get date for first day of the week
    let diff = calendar.component(.weekday, from: date) - calendar.firstWeekday
    guard let firstDate = calendar.date(byAdding: .day, value: -(diff < 0 ? 7 + diff : diff), to: date) else {
        return nil
    }

    //Generate start and end date for the duration 
    var weeks = [DateInterval(start: firstDate, end: calendar.date(byAdding: .day, value: 6, to: firstDate)!)]
    for week in 1..<duration {
        guard let firstDayOfWeek = calendar.date(byAdding: .day, value: 7, to: weeks[week - 1].start),
            let lastDayOfWeek = calendar.date(byAdding: .day, value: 6, to: firstDayOfWeek) else { return nil }

        weeks.append(DateInterval(start: firstDayOfWeek, end: lastDayOfWeek))
    }
    return weeks
}

и для использования ее и печати даты, которые вы можете сделать

if let weeks = weeks(from: Date(), duration: 5) {
    let formatter = DateFormatter()
    formatter.dateFormat = "MMMM dd"

    for interval in weeks {
        print("\(formatter.string(from: interval.start)) -  \(formatter.string(from: interval.end))")
    }
}

, что выводит

13 июля - 19 июля 20 - 26 июля 27 июля - 02 августа 03 августа - 09 августа 10 - 16 августа

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...