Swift - 从一系列工作日获取下一个日期

时间:2017-02-10 06:40:31

标签: swift swift3 nsdate nscalendar

上下文

我正在创建一个应用程序,其中包含截止日期的任务,一旦完成,我想根据用户选择的星期几重复模式根据新日期设置新的截止日期。

我将截止日期保存为日期。我将重复模式保存为Int32(星期日为1,星期一为2,星期二为4 ......)但是我可以很容易地将它转换为代表每一天的字符串数组或数字

问题

如何将下一个截止日期作为日期(所以我可以重复该任务)?

示例

如果我有一个在星期六完成的任务,并且每周一和周三都有重复模式,我希望将其设置为下周一。如果他们在周一或周二完成,我想设置下周三。

选择重复模式的照片

选择其他日期时,永远不会选择月份。我知道如何处理本月。问题在于一周的日子

3 个答案:

答案 0 :(得分:2)

永远不要将86400用于日期数学,CalendarIndexSet有强大的方法来执行此操作:

// 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)

答案 1 :(得分:1)

我希望这段代码可以提供帮助

$n = 10000000000000000000001;
$n = str_replace(",", "", number_format($n));
可以使用其中一个Date类初始化程序在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

答案 2 :(得分:0)

func getdateArryFromWeekdays(_ date: Date, onWeekdaysForNotify weekdays:[Int]) -> [Date]{
    var correctedDate: [Date] = [Date]()
    let now = Date()
    let calendar = Calendar(identifier: Calendar.Identifier.gregorian)
    let flags: NSCalendar.Unit = [NSCalendar.Unit.weekday, NSCalendar.Unit.weekdayOrdinal, NSCalendar.Unit.day]
    let dateComponents = (calendar as NSCalendar).components(flags, from: date)
    let weekday:Int = dateComponents.weekday!

    //no repeat
    if weekdays.isEmpty{
        //scheduling date is eariler than current date
        if date < now {
            //plus one day, otherwise the notification will be fired righton
            correctedDate.append((calendar as NSCalendar).date(byAdding: NSCalendar.Unit.day, value: 1, to: date, options:.matchNextTime)!)
        }
        else { //later
            correctedDate.append(date)
        }
        return correctedDate
    }
        //repeat
    else {
        let daysInWeek = 7
        correctedDate.removeAll(keepingCapacity: true)
        for wd in weekdays {

            var wdDate: Date!
            //schedule on next week
            if compare(weekday: wd, with: weekday) == .before {
                wdDate =  (calendar as NSCalendar).date(byAdding: NSCalendar.Unit.day, value: wd+daysInWeek-weekday, to: date, options:.matchStrictly)!
            }
            else { //after
                wdDate =  (calendar as NSCalendar).date(byAdding: NSCalendar.Unit.day, value: wd-weekday, to: date, options:.matchStrictly)!
            }

            //fix second component to 0
            wdDate = correctSecondComponent(date: wdDate, calendar: calendar)
            correctedDate.append(wdDate)
        }
        return correctedDate
     }

}
func correctSecondComponent(date: Date, calendar: Calendar = Calendar(identifier: Calendar.Identifier.gregorian))->Date {
    let second = calendar.component(.second, from: date)
    let d = (calendar as NSCalendar).date(byAdding: NSCalendar.Unit.second, value: -second, to: date, options:.matchStrictly)!
    return d
}
enum weekdaysComparisonResult {
    case before
    case same
    case after
}