2015-07-31 8 views
7

Angenommen, heute ist Mittwoch. Ich kann einen NSDate hinunter in NSDateComponents brechen, aber ich muss den NSDate mit dem nächsten kommenden Montag finden. Wenn heute Montag ist, dann ist heute der nächste kommende Montag. Was ist der richtige Weg, dies zu erreichen?Finde NSDate für den nächsten spezifischen Wochentag für jedes Datum

+0

verwenden Sie können sich https://github.com/mysterioustrousers/MTDates, und es gibt eine 'mt_startOfNextWeek;' - Methode. –

+0

Ich brauche eine Lösung ohne Bibliotheken für dritte Teile –

+2

Meinst du den nächsten * kommenden * Montag, oder nur den * nächsten * (was könnte in der Vergangenheit oder in der Zukunft sein)? –

Antwort

20

Sie nextDateAfterDate: Methode auf NSCalendar Objekt verwenden können, um dies zu erreichen,

let now = Date() // today 

var matchingComponents = DateComponents() 
matchingComponents.weekday = 2 // Monday 

let comingMonday = Calendar.current.nextDate(after: now, 
               matching: matchingComponents, 
               matchingPolicy:.nextTime) 

Hier ist eine einfache Methode, nächsten Montag zu finden. Wenn heute Montag ist, kommt die folgende Funktion heute oder sonst der nächste Montag zurück. Beachten Sie, dass de_POSIX_US so verwendet wird, dass die Tage übereinstimmen. Wenn die locale ist en_POSIX_US, Wochentage Symbole geworden,

["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"] 

Und hier ist, wie diese Tage eingesetzt werden könnten,

func findNext(_ day: String, afterDate date: Date) -> Date? { 

    var calendar = Calendar.current 
    calendar.locale = Locale(identifier: "en_US_POSIX") 

    let weekDaySymbols = calendar.weekdaySymbols 
    let indexOfDay = weekDaySymbols.index(of: day) 

    assert(indexOfDay != nil, "day passed should be one of \(weekDaySymbols), invalid day: \(day)") 

    let weekDay = indexOfDay! + 1 

    let components = calendar.component(.weekday, from: date) 

    if components == weekDay { 
     return date 
    } 

    var matchingComponents = DateComponents() 
    matchingComponents.weekday = weekDay // Monday 

    let nextDay = calendar.nextDate(after: date, 
            matching: matchingComponents, 
            matchingPolicy:.nextTime) 
    return nextDay! 
} 


let nextMonday = findNext("Monday", afterDate: Date()) 
let mondayAfterThat = findNext("Monday", afterDate: nextMonday!) 

let thursday = findNext("Thursday", afterDate: mondayAfterThat!) 
+0

das ist die beste Lösung, die ich denke :) –

+2

Es ist erstaunlich, dass NSCalendar's iOS 8 Methoden immer noch undokumentiert in der Referenzbibliothek sind . – Desdenova

+0

Ja, sie scheinen NSCalendar und Geschwister viele neue Apis hinzugefügt zu haben. Es wäre wirklich gut, sie dokumentieren zu lassen. – Sandeep

-4

Sie können die Woche Tag erhalten, indem NSDateComponents verwenden und die Intervall Tage berechnen, verwenden dann dateByAddingTimeInterval von NSDate wie so:

let now = NSDate() 
let calendar: NSDateComponents = NSCalendar.currentCalendar().components(NSCalendarUnit.CalendarUnitWeekday, fromDate: now) 
let weekday = calendar.weekday // 1 = Sunday, 2 = Monday 

// You get input the weekday here and calculate the interval 

// exmaple for moving to the next day 
let expectedDate = now.dateByAddingTimeInterval(1 * 24 * 60 * 60) 

// exmaple for moving to yesterday 
let yesterday = now.dateByAddingTimeInterval(-1 * 24 * 60 * 60) 
+1

** Verwenden Sie nicht 24 * 60 * 60 Sekunden als Dauer eines Tages (denken Sie an Sommerzeitübergänge). –

+0

@MartinR Entschuldigung. Ich folge nicht. Kannst du das nochmal erklären? –

+0

Tage können 23, 24, 25 Stunden lang sein, aufgrund der Sommerzeit – vikingosegundo

2

für Ziel iOS> = 8-Lösung Verwendung GeneratorOfOne

sonst können Sie diese

let now = NSDate() 
var lastMonday:NSDate? 
var nextMonday:NSDate? 
var start:NSDate?   

var interval:NSTimeInterval = 0 // holds the length of a week. can differ for Daylight Saving Time 
let cal = NSCalendar(calendarIdentifier: NSCalendarIdentifierGregorian)! // have a own calendar object for this calculation to guarantee that the next line does not influence other calculations 
cal.firstWeekday = 2    // make sure first day of week is Monday. 


cal.rangeOfUnit(NSCalendarUnit.CalendarUnitWeekOfMonth, startDate: &lastMonday, interval:&interval, forDate: now)  // monday of current week 
nextMonday = lastMonday?.dateByAddingTimeInterval(interval) // add a weeks length to the last weeks's monday 
println(nextMonday) 
Verwandte Themen