Предположим, что сегодня среда. Я могу разбить NSDate
на NSDateComponents
, но мне нужно найти NSDate
в следующий предстоящий понедельник. Если сегодня понедельник, то следующий предстоящий понедельник будет сегодня. Каков правильный способ добиться этого?
Найти NSDate для следующего ближайшего определенного дня недели для любой даты
Ответы (3)
Для этого вы можете использовать метод nextDateAfterDate:
для объекта NSCalendar
,
let now = Date() // today
var matchingComponents = DateComponents()
matchingComponents.weekday = 2 // Monday
let comingMonday = Calendar.current.nextDate(after: now,
matching: matchingComponents,
matchingPolicy:.nextTime)
Вот простой способ найти следующий понедельник. Если сегодня понедельник, следующая функция возвращает значение сегодня или ближайший следующий понедельник. Обратите внимание, что он использует en_POSIX_US, чтобы можно было сопоставить дни. Если локаль en_POSIX_US, символы дней недели становятся
["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"]
И вот как можно было бы использовать эти дни,
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!)
person
Sandeep
schedule
31.07.2015
это лучшее решение, я думаю :)
- person Bartłomiej Semańczyk; 31.07.2015
Удивительно, что методы
NSCalendar
для iOS 8 до сих пор не задокументированы в справочной библиотеке.
- person Desdenova; 31.07.2015
Да, кажется, они добавили много новых API в NSCalendar и его собратьев. Было бы очень хорошо, если бы они были задокументированы.
- person Sandeep; 31.07.2015
Monday не будет работать для других языков, например,
Monday
на польском языке будет Poniedziałek
. Я думаю, что поиск по названию — не лучшее решение, так как календари в устройствах автоматически локализуются.
- person Bartłomiej Semańczyk; 31.07.2015
По этой причине локаль используется для календаря с en_US_POSIX, обратите внимание, что он использует системный календарь, но устанавливает локаль en_US_POSIX, просто чтобы извлечь английское имя.
- person Sandeep; 31.07.2015
Великолепно! Большое спасибо!
- person Frédéric Adda; 01.12.2016
для целевой iOS >= 8 используйте решение GeneratorOfOne
иначе вы можете использовать это
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)
person
vikingosegundo
schedule
31.07.2015
Вы можете получить день недели с помощью NSDateComponents
и вычислить дни интервала, а затем использовать dateByAddingTimeInterval
из NSDate
следующим образом:
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)
person
Lucas Huang
schedule
31.07.2015
Не используйте 24*60*60 секунд в качестве продолжительности дня (подумайте о переходе на летнее время).
- person Martin R; 31.07.2015
@MartinR извини. Я не понимаю. Можете ли вы объяснить это снова?
- person Lucas Huang; 31.07.2015
дни могут длиться 23, 24, 25 часов из-за перехода на летнее время.
- person vikingosegundo; 31.07.2015
mt_startOfNextWeek;
. - person Dániel Nagy   schedule 31.07.2015