2016-02-28 24 views
3

我正在實現一個日曆視圖,並且我希望它在包含特定日期的一週開始時開始。例如。如果目標日期是星期一,2016年2月29日,與當前日曆設置爲在週日開始,我想我的觀點入手星期天,2月28日我如何從NSDate中找到一週的開始?

這似乎應該是簡單的:

let calendar = NSCalendar.currentCalendar() 
let firstDate = calendar.nextDateAfterDate(targetDate, 
        matchingUnit: .Weekday, 
          value: calendar.firstWeekday, 
         options: .SearchBackwards) 

但這種失敗:

終止應用程序由於未捕獲的異常 'NSInvalidArgumentException',理由是: '從精確地設定一個選項{NSCalendarMatchPreviousTimePreservingSmallerUnits,NSCalendarMatchNextTimePreservingSmallerUnits,NSCalendarMatchNextTime}必須指定。'

我能得到基本上是我想:

let firstDate = calendar.nextDateAfterDate(firstDate, 
        matchingUnit: .Weekday, 
          value: calendar.firstWeekday, 
         options: .MatchPreviousTimePreservingSmallerUnits)? 
        .dateByAddingTimeInterval(-7 * 84600) 

但它似乎是一個不好的做法,因爲有時候在一天的秒數不是86400

有更好的方法?

回答

18

可以使用NSCalendar方法dateFromComponents傳遞.YearForWeekOfYear,.WeekOfYear組件從任何日期,將返回星期的第一天,從使用的日曆。所以如果你希望星期天只使用公曆。如果你想獲得週一作爲一週的第一天,你可以使用NSCalendar ISO8601,你可以在這個answer

的Xcode 8.3.2看到雨燕•3.1或更高版本

extension Calendar { 
    static let gregorian = Calendar(identifier: .gregorian) 
} 
extension Date { 
    var startOfWeek: Date? { 
     return Calendar.gregorian.date(from: Calendar.gregorian.dateComponents([.yearForWeekOfYear, .weekOfYear], from: self)) 
    } 
} 

用法:

Date().startOfWeek // "Oct 15, 2017 at 1:00 AM" (note that daylight savings took effect last Sunday, thats why it shows 1am) 
+2

謝謝!這是一個很好的方式來做到這一點。 – Aneel

+0

@歡迎你歡迎 –

+0

這是實現它的很酷的方式,但夏令時有一個小問題。這可以固定用下面的代碼:'VAR startOfWeek:{的NSDate讓日期= Calendar.gregorian.dateFromComponents(Calendar.gregorian.components([YearForWeekOfYear,.WeekOfYear。],FROM日期:自));!讓dslTimeOffset = NSTimeZone.local.daylightSavingTimeOffset(for:date); return date.addingTimeInterval(dslTimeOffset); }' – artificis

0

基本上使用

NSCalender

dateByAddingComponents

。爲了解決你的問題是嘗試使用此代碼示例:

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) { 
     print(beginningOfWeek) 
    } 
} 
+0

謝謝!雖然我最終以另一種方式解決問題,但這個答案幫助我更好地理解了如何使用dateByAddingComponents。 – Aneel

0

日曆有(比如一年的每週或每月在給定的時間間隔的開始日期查找機制)包含給定日期:

let dateFormatter = DateFormatter() 
dateFormatter.dateFormat = "yyyy-MM-dd" 
let date = dateFormatter.date(from: "2017-01-07") 

if let date = date { 
    let calendar = Calendar(identifier: .gregorian) 

    var startDate : Date = Date() 
    var interval : TimeInterval = 0 

    if calendar.dateInterval(of: .weekOfYear, start: &startDate, interval: &interval, for: date) { 
     print("Start of week is \(startDate)") 
     // prints "Start of week is 2017-01-01 06:00:00 +0000" 
    } 
}