Как получить даты для каждой пятницы между двумя датами? - PullRequest
0 голосов
/ 24 октября 2019

В настоящее время я использую следующий код для возврата массива дат для каждого дня между двумя датами, включая сегодняшнюю дату и саму последнюю дату. Это прекрасно работает.

  • Однако, как бы я изменил то, что я уже делаю, чтобы сделать то же самое в противном случае, но вместо этого вернуть массив дат каждую пятницу между датами? Например, если функция была вызвана в среду с 23 октября 2019 года для возврата каждую пятницу до 10 ноября, первой датой будет пт 25, 1 ноября, а затем 8 ноября.
  • Как бы я поступил так жевещь, как указано выше, но 1-го числа каждого месяца? Если бы я вызывал функцию в среду, 23 октября 2019 года, чтобы возвращать первое число каждого месяца до 16 декабря. Массив должен содержать 1 ноября и 1 декабря.
func dates(for date: String) -> [String] {
    // first get the endDate
    guard var endDate = Formatter.date.date(from: date) else { return [] }
    // for calendrical calculations you should use noon time
    endDate = Calendar.current.date(bySettingHour: 12, minute: 0, second: 0, of: endDate)!
    // lets get todays noon time to start
    var date = Calendar.current.date(bySettingHour: 12, minute: 0, second: 0, of: Date())!
    var dates: [String] = []
    // while date less than or equal to end date
    while date <= endDate {
        // add the formatted date to the array
        dates.append( Formatter.date.string(from: date))
        // increment the date by one day
        date = Calendar.current.date(byAdding: .day, value: 1, to: date)!
    }

    return dates
}

Ответы [ 2 ]

1 голос
/ 24 октября 2019

Вам просто нужно добавить параметр дня недели в ваш метод и проверить, если день недели даты внутри цикла перед добавлением его в ваш массив:

extension Formatter {
    static let date = DateFormatter()
}

func dates(for date: String, weekday: Int? = nil) -> [String] {
    Formatter.date.locale = Locale(identifier: "en_US_POSIX")
    Formatter.date.dateFormat = "yyyy-MM-dd"
    // first get the endDate
    guard var endDate = Formatter.date.date(from: date) else { return [] }
    // for calendrical calculations you should use noon time
    endDate = Calendar.current.date(bySettingHour: 12, minute: 0, second: 0, of: endDate)!
    // lets get todays noon time to start
    var date = Calendar.current.date(bySettingHour: 12, minute: 0, second: 0, of: Date())!
    var dates: [String] = []
    // while date less than or equal to end date
    while date <= endDate {
        if weekday == nil {
            dates.append(Formatter.date.string(from: date))
            date = Calendar.current.date(byAdding: .day, value: 1, to: date)!
        } else if let weekday = weekday, Calendar.current.component(.weekday, from: date) == weekday {
            // add the formatted date to the array
            dates.append(Formatter.date.string(from: date))
            date = Calendar.current.date(byAdding: .weekOfYear, value: 1, to: date)!
        } else {
            date = Calendar.current.date(byAdding: .day, value: 1, to: date)!
        }
    }
    return dates
}

dates(for: "2019-12-25")  // ["2019-10-23", "2019-10-24", "2019-10-25", "2019-10-26", "2019-10-27", "2019-10-28", "2019-10-29", "2019-10-30", "2019-10-31", "2019-11-01", "2019-11-02", "2019-11-03", "2019-11-04", "2019-11-05", "2019-11-06", "2019-11-07", "2019-11-08", "2019-11-09", "2019-11-10", "2019-11-11", "2019-11-12", "2019-11-13", "2019-11-14", "2019-11-15", "2019-11-16", "2019-11-17", "2019-11-18", "2019-11-19", "2019-11-20", "2019-11-21", "2019-11-22", "2019-11-23", "2019-11-24", "2019-11-25", "2019-11-26", "2019-11-27", "2019-11-28", "2019-11-29", "2019-11-30", "2019-12-01", "2019-12-02", "2019-12-03", "2019-12-04", "2019-12-05", "2019-12-06", "2019-12-07", "2019-12-08", "2019-12-09", "2019-12-10", "2019-12-11", "2019-12-12", "2019-12-13", "2019-12-14", "2019-12-15", "2019-12-16", "2019-12-17", "2019-12-18", "2019-12-19", "2019-12-20", "2019-12-21", "2019-12-22", "2019-12-23", "2019-12-24", "2019-12-25"]
dates(for: "2019-12-25", weekday: 6) // ["2019-10-25", "2019-11-01", "2019-11-08", "2019-11-15", "2019-11-22", "2019-11-29", "2019-12-06", "2019-12-13", "2019-12-20"]

func firstDayOfTheMonth(until date: String) -> [String] {
    Formatter.date.locale = Locale(identifier: "en_US_POSIX")
    Formatter.date.dateFormat = "yyyy-MM-dd"
    guard let endDate = Formatter.date.date(from: date) else { return [] }
    var date = Date()
    var dates: [String] = []
    // while date less than or equal to end date
    while let firstDayOfTheMonth = Calendar.current.nextDate(after: date, matching: .init(day: 1), matchingPolicy: .nextTime), firstDayOfTheMonth <= endDate {
        dates.append(Formatter.date.string(from: firstDayOfTheMonth))
        date = firstDayOfTheMonth
    }
    return dates
}

firstDayOfTheMonth(until: "2019-12-25")  // ["2019-11-01", "2019-12-01"]
0 голосов
/ 24 октября 2019

Вы можете получить день недели для любого дня недели с помощью:

let weekDayIndex = Calendar.current.component(.weekday, from: Date())

Пятница - это день 5. Вы можете получить название любого дня с помощью:

print(Calendar.current.weekdaySymbols[weekDayIndex])

Так что просто переберите все свои даты и отфильтруйте все, что не соответствует 5 рабочему дню, и у вас есть ответ:

func fridays(in dates: [Date]) {
  dates.filter { Calendar.current.component(.weekday, from: $0) == 5 }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...