Swift - получить следующую дату из массива будних дней

Контекст

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

Я сохраняю сроки как Дата. Я сохраняю шаблон повторения как Int32 (1 для воскресенья, 2 для понедельника, 4 для вторника ...), но я могу легко получить его в массиве строк или чисел, представляющих каждый день

Проблема

Как мне получить следующий срок как Дата (чтобы я мог повторить задачу)?

Пример

Если у меня есть задача, которая выполняется в субботу и повторяется каждый понедельник и среду, я хочу, чтобы она была установлена ​​на следующий понедельник. Если они будут завершены в понедельник или вторник, я хочу установить следующую среду.

Фотография выбора повторяющегося узора

Месяц никогда не выбирается, если выбраны другие дни. Я знаю, как вести себя с Месяцем. Проблема как раз в днях недели


person toiavalle    schedule 10.02.2017    source источник
comment
какой-то код был бы полезен, мы не читаем мысли ...   -  person Mr. Xcoder    schedule 10.02.2017


Ответы (2)


Никогда не используйте 86400 для вычисления даты, Calendar и IndexSet используйте для этого мощные методы:

// Put your weekday indexes in an `IndexSet`
let weekdaySet = IndexSet([1, 2, 4, 7]) // Sun, Mon, Wed and Sat

// Get the current calendar and the weekday from today
let calendar = Calendar.current
var weekday =  calendar.component(.weekday, from: Date())

// Calculate the next index
if let nextWeekday = weekdaySet.integerGreaterThan(weekday) {
    weekday = nextWeekday
} else {
    weekday = weekdaySet.first!
}

// Get the next day matching this weekday
let components = DateComponents(weekday: weekday)
calendar.nextDate(after: Date(), matching: components, matchingPolicy: .nextTime)
person vadian    schedule 12.02.2017

Надеюсь, этот фрагмент может быть полезен

let SecondsPerDay: Int = (24 * 60 * 60)

enum DayOfWeek: Int
{
    case sunday = 1
    case monday = 2
    case tuesday = 3
    case wendnesday = 4
    case thrusday = 5
    case friday = 6
    case saturday = 7

    /**
        Convert a date to a enumeration member
    */
    static func day(from date: Date) -> DayOfWeek
    {
        let formatter: DateFormatter = DateFormatter()
        formatter.dateFormat = "e"


        let day_number: Int = Int(formatter.string(from: date))!

        return DayOfWeek(rawValue: day_number)
    }
}


/**
    Calculate the `TimeInterval` between days contained
    in user preferences.

    - Parameter days: Period selected by user
    - Returns: Interval between dates days
*/
func calculatePattern(withDays days: [DayOfWeek]) -> [TimeInterval]
{
    var pattern: [TimeInterval] = [TimeInterval]()

    for (index, day) in days.enumerated()
    {
        let distance: Int = (index == (days.count - 1)) ?  (7 - (day.rawValue - days[0].rawValue)) : days[index + 1].rawValue - day.rawValue

        let interval: TimeInterval = TimeInterval(SecondsPerDay * distance)

        pattern.append(interval)
    }

    return pattern
}

func nextDay(from days: [DayOfWeek]) -> DayOfWeek
{
    let today: DayOfWeek = DayOfWeek.day(from: Date())

    guard let days = days.filter({ $0.rawValue > today.rawValue }) else
    {
        return days.first!
    }

    return days.first!
}



let selectedDays: [DayOfWeek] = [ .monday, .wendnesday, .sunday, .saturday ]

// Pass the array sorted by day in week
let intervals: [TimeInterval] = calculatePattern(withDays: selectedDays.sorted(by: { $0.rawValue < $1.rawValue}))

for interval in intervals
{
    print(interval)
}

TimeInterval можно преобразовать в Date с помощью одного из инициализаторов класса Date.

person Adolfo    schedule 10.02.2017
comment
Спасибо, это полезно. Но как я могу отсортировать даты по тому, насколько они близки к текущей дате, чтобы я мог получить более раннюю? @Adolfo - person toiavalle; 12.02.2017
comment
Добавлена ​​новая функция, которая вычисляет следующий день из массива DayOfWeek - person Adolfo; 12.02.2017