Swift - 前一周的开始日和结束日

Swift - Start day and end day of the week before previous week

今天是 3 月 6 日星期五。如何找到 2 月 16 日是开始日,2 月 22 日是前一周的结束日。 16 是我的国家保加利亚在美国将是 15 和 21 我使用 .currentCalendar()

像这样的东西应该可以工作:

let cal = NSCalendar.currentCalendar()

let components = NSDateComponents()
components.weekOfYear -= 1

if let date = cal.dateByAddingComponents(components, toDate: NSDate(), options: NSCalendarOptions(0)) {
    var beginningOfWeek: NSDate?
    var weekDuration = NSTimeInterval()
    if cal.rangeOfUnit(.CalendarUnitWeekOfYear, startDate: &beginningOfWeek, interval: &weekDuration, forDate: date) {
        let endOfWeek = beginningOfWeek?.dateByAddingTimeInterval(weekDuration)
        print(beginningOfWeek) // Optional(2015-02-15 05:00:00 +0000)
        print(endOfWeek) // Optional(2015-02-22 05:00:00 +0000)
    }
}

一个更简单的 Swift 2 替代方案作为扩展,源自 :

extension: NSDate {
    func startOfWeek(weekday: Int?) -> NSDate? {
        guard
            let cal: NSCalendar = NSCalendar.currentCalendar(),
            let comp: NSDateComponents = cal.components([.YearForWeekOfYear, .WeekOfYear], fromDate: self) else { return nil }
        comp.to12pm()
        cal.firstWeekday = weekday ?? 1
        return cal.dateFromComponents(comp)!
    }

    func endOfWeek(weekday: Int) -> NSDate? {
        guard
            let cal: NSCalendar = NSCalendar.currentCalendar(),
            let comp: NSDateComponents = cal.components([.WeekOfYear], fromDate: self) else { return nil }
        comp.weekOfYear = 1
        comp.day -= 1
        comp.to12pm()
        return cal.dateByAddingComponents(comp, toDate: self.startOfWeek(weekday)!, options: [])!
    }
}

用法:

// Use 2 for Monday, 1 for Sunday:
print(NSDate().startOfWeek(1)!) // "2016-01-24 08:00:00 +0000\n"
print(NSDate().endOfWeek(1)!) // "2016-01-30 08:00:00 +0000\n"

为了防止 DST 等,您还应该实施扩展以强制时间为中午 12 点:

internal extension NSDateComponents {
    func to12pm() {
        self.hour = 12
        self.minute = 0
        self.second = 0
    }
}

如果有人在寻找 swift 3 个答案:

func startOfWeek(weekday: Int?) -> Date {
    var cal = Calendar.current
    var component = cal.dateComponents([.yearForWeekOfYear, .weekOfYear], from: self)
    component.to12am()
    cal.firstWeekday = weekday ?? 1
    return cal.date(from: component)!
}

func endOfWeek(weekday: Int) -> Date {
    let cal = Calendar.current
    var component = DateComponents()
    component.weekOfYear = 1
    component.day = -1
    component.to12pm()
    return cal.date(byAdding: component, to: startOfWeek(weekday: weekday))!
}

我设置为那天的00:00:00

 internal extension DateComponents {
    mutating func to12am() {
        self.hour = 0
        self.minute = 0
        self.second = 0
    }

    mutating func to12pm(){
        self.hour = 23
        self.minute = 59
        self.second = 59
    }
}

Swift 4+:

主要使用 Calendar 并借助 DateComponents 的一种非常直接的方法:

  1. 获取Date
  2. 转到上一周
    • Calendar.current.date(byAdding: .weekdayOrdinal, value: -1, to: aDate)
  3. 获取当前工作日
    • Calendar.current.component(.weekday, from: bDate)
  4. 从这个工作日计算偏移量
    • 到达一周开始的负偏移量
    • 到周末到达的正偏移量
  5. 使用偏移量转到所需日期
    • Calendar.current.date(byAdding: .day, value: offset, to: bDate)

解决方案:

extension Date {
    var firstWeekdayOfLastWeek: Date? {
        guard let previousWeek = Calendar.current.date(byAdding: .weekdayOrdinal,
                                                       value: -1, to: self)
        else { return nil }
        
        let offsetToFirstWeekday: Int = {
            let currentWeekday = Calendar.current.component(.weekday, from: previousWeek)
            guard currentWeekday > 0 else { return 0 }
            return 1 - currentWeekday
        }()
        
        let result = Calendar.current.date(byAdding: .day,
                                           value: offsetToFirstWeekday,
                                           to: previousWeek)
        return result
    }
    
    var lastWeekdayOfLastWeek: Date? {
        guard let previousWeek = Calendar.current.date(byAdding: .weekdayOrdinal,
                                                       value: -1, to: self)
        else { return nil }
        
        let offsetToLastWeekday: Int = {
            let currentWeekday = Calendar.current.component(.weekday, from: previousWeek)
            return 7 - currentWeekday
        }()
        
        let result = Calendar.current.date(byAdding: .day,
                                           value: offsetToLastWeekday,
                                           to: previousWeek)
        return result
    }
}

用法示例:

let formatter = DateFormatter()
formatter.dateStyle = .long

let date = Date()

//My current system date (as of time of writing)
print(formatter.string(from: currentDate))                  //December 11, 2020

//Results (my system has Sunday as the start of the week)
print(formatter.string(from: date.firstWeekdayOfLastWeek!)) //November 29, 2020
print(formatter.string(from: date.lastWeekdayOfLastWeek!))  //December 5, 2020

强制展开仅供示例使用