2015-07-31 28 views
7

Supponiamo che oggi sia mercoledì. Posso rompere uno NSDate in NSDateComponents, ma ho bisogno di trovare il NSDate con il prossimo imminente Lunedi. Se oggi è lunedì, il prossimo è il imminente. Qual è il modo giusto per raggiungere questo obiettivo?Trova NSDate per il giorno della settimana successivo più vicino per qualsiasi data

+0

Puoi dare un'occhiata a https://github.com/mysterioustrousers/MTDates e ha un metodo 'mt_startOfNextWeek;'. –

+0

Ho bisogno di una soluzione senza librerie di terze parti –

+2

Intendi il prossimo * imminente * lunedì, o solo il * più vicino * (che potrebbe essere nel passato o nel futuro)? –

risposta

20

È possibile utilizzare nextDateAfterDate: metodo su NSCalendar oggetto per raggiungere questo obiettivo,

let now = Date() // today 

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

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

Ecco, è un metodo semplice per trovare il prossimo lunedì. Se oggi è lunedì, la funzione seguente ritorna oggi o il lunedì successivo più vicino. Si noti che utilizza en_POSIX_US in modo che i giorni possano essere abbinati. Quando il locale è en_POSIX_US, simboli nei giorni feriali diventano,

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

Ed, ecco come potrebbero essere utilizzati questi giorni,

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

questa è la soluzione migliore penso :) –

+2

È sorprendente che i metodi di iOS 8 di 'NSCalendar' sono ancora non documentati sulla libreria di riferimento . – Desdenova

+0

Sì, sembra che abbiano aggiunto molte nuove API a NSCalendar e fratelli. Sarebbe davvero bello averli documentati. – Sandeep

-4

È possibile ottenere il giorno della settimana utilizzando NSDateComponents e calcolare i giorni di intervallo, quindi utilizzare dateByAddingTimeInterval da NSDate in questo modo:

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

** Non ** utilizzare 24 * 60 * 60 secondi come durata di un giorno (pensare alle transizioni dell'ora legale). –

+0

@MartinR scusate. Io non seguo. Puoi spiegarlo di nuovo? –

+0

giorni possono essere 23, 24, 25 ore, a causa di ora legale – vikingosegundo

2

per obiettivo iOS> = 8 uso soluzione di GeneratorOfOne

altrimenti puoi usare questo

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)