简体   繁体   English

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

[英]Swift - Start day and end day of the week before previous week

Today is Friday 6 March.今天是 3 月 6 日星期五。 How to find that 16 Feb is the start day and 22 Feb is the end day of the week before previous week.如何找到2月16日是开始日,2月22日是前一周的结束日。 16 is for my country Bulgaria in USA will be 15 and 21 I use .currentCalendar() 16 是我的国家保加利亚在美国将是 15 和 21 我使用 .currentCalendar()

Something like this should work:这样的事情应该工作:

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

A simpler Swift 2 alternative as an extension, derived from Martin R's answer for getting the end of the month :一个更简单的 Swift 2 替代方案作为扩展,源自Martin R 对获得月底的回答

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: [])!
    }
}

Usage:用法:

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

To guard against DST and such, you should also implement an extension to force the time to 12 pm:为了防止 DST 等,您还应该实施扩展以将时间强制为下午 12 点:

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

If anyone looking for swift 3 answer:如果有人在寻找 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))!
}

I set to 00:00:00 of that day我设置为当天的 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+:斯威夫特 4+:

A very straightforward approach using mainly Calendar with the help of DateComponents :DateComponents的帮助下主要使用Calendar一种非常简单的方法:

  1. Get Date获取Date
  2. Go to previous week转到上周
    • Calendar.current.date(byAdding: .weekdayOrdinal, value: -1, to: aDate)
  3. Get the current weekday获取当前工作日
    • Calendar.current.component(.weekday, from: bDate)
  4. Compute an offset from this weekday计算这个工作日的偏移量
    • Negative offset to reach the start of week负抵消到达一周的开始
    • Positive offset to the reach end of the week正抵消到达周末
  5. Use offset to go to the required date使用偏移量转到所需的日期
    • Calendar.current.date(byAdding: .day, value: offset, to: bDate)

Solution:解决方案:

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
    }
}

Usage Example:用法示例:

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

Force unwrap is for example purposes only强制解包仅用于示例目的

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM