我只想要一个以NSDate的形式包含一年中所有星期一的数组,但是很快。 我在目标-c中使用以下代码,但不知道如何在swift中使用它。
NSDate *pickerDate = [NSDate date];
NSLog(@"pickerDate: %@", pickerDate);
NSDateComponents *dateComponents;
NSCalendar *calendar = [NSCalendar currentCalendar];
dateComponents = [calendar components:NSWeekdayCalendarUnit fromDate:pickerDate];
NSInteger firstMondayOrdinal = 9 - [dateComponents weekday];
dateComponents = [[NSDateComponents alloc] init];
[dateComponents setDay:firstMondayOrdinal];
NSDate *firstMondayDate = [calendar dateByAddingComponents:dateComponents toDate:pickerDate options:0];
dateComponents = [[NSDateComponents alloc] init];
[dateComponents setWeek:1];
for (int i=0; i<64; i++) {
[dateComponents setWeek:i];
NSDate *mondayDate = [calendar dateByAddingComponents:dateComponents toDate:firstMondayDate options:0];
NSLog(@"week#: %i, mondayDate: %@", i, mondayDate);
}
答案 0 :(得分:9)
Xcode 8或更高版本•Swift 3或更高版本
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))!
}
var addingOneWeek: Date {
return Calendar.gregorian.date(byAdding: DateComponents(weekOfYear: 1), to: self)!
}
var nextSunday: Date {
return startOfWeek.addingOneWeek
}
func nextFollowingSundays(_ limit: Int) -> [Date] {
precondition(limit > 0)
var sundays = [nextSunday]
sundays.reserveCapacity(limit)
return [nextSunday] + (0..<limit-1).compactMap { _ in
guard let next = sundays.last?.addingOneWeek else { return nil }
sundays.append(next)
return next
}
}
}
<强>用法:强>
let today = Date()
let nextFollowingSundays = today.nextFollowingSundays(52)
nextFollowingSundays.forEach { sunday in
print(sunday.description(with: .current), terminator: "\n")
}
// ["Feb 17, 2019 at 12:00 AM", "Feb 24, 2019 at 12:00 AM", "Mar 3, 2019 at 12:00 AM", "Mar 10, 2019 at 12:00 AM", "Mar 17, 2019 at 12:00 AM", "Mar 24, 2019 at 12:00 AM", "Mar 31, 2019 at 12:00 AM", "Apr 7, 2019 at 12:00 AM", "Apr 14, 2019 at 12:00 AM", "Apr 21, 2019 at 12:00 AM", "Apr 28, 2019 at 12:00 AM", "May 5, 2019 at 12:00 AM", "May 12, 2019 at 12:00 AM", "May 19, 2019 at 12:00 AM", "May 26, 2019 at 12:00 AM", "Jun 2, 2019 at 12:00 AM", "Jun 9, 2019 at 12:00 AM", "Jun 16, 2019 at 12:00 AM", "Jun 23, 2019 at 12:00 AM", "Jun 30, 2019 at 12:00 AM", "Jul 7, 2019 at 12:00 AM", "Jul 14, 2019 at 12:00 AM", "Jul 21, 2019 at 12:00 AM", "Jul 28, 2019 at 12:00 AM", "Aug 4, 2019 at 12:00 AM", "Aug 11, 2019 at 12:00 AM", "Aug 18, 2019 at 12:00 AM", "Aug 25, 2019 at 12:00 AM", "Sep 1, 2019 at 12:00 AM", "Sep 8, 2019 at 12:00 AM", "Sep 15, 2019 at 12:00 AM", "Sep 22, 2019 at 12:00 AM", "Sep 29, 2019 at 12:00 AM", "Oct 6, 2019 at 12:00 AM", "Oct 13, 2019 at 12:00 AM", "Oct 20, 2019 at 12:00 AM", "Oct 27, 2019 at 12:00 AM", "Nov 3, 2019 at 1:00 AM", "Nov 10, 2019 at 1:00 AM", "Nov 17, 2019 at 12:00 AM", "Nov 24, 2019 at 12:00 AM", "Dec 1, 2019 at 12:00 AM", "Dec 8, 2019 at 12:00 AM", "Dec 15, 2019 at 12:00 AM", "Dec 22, 2019 at 12:00 AM", "Dec 29, 2019 at 12:00 AM", "Jan 5, 2020 at 12:00 AM", "Jan 12, 2020 at 12:00 AM", "Jan 19, 2020 at 12:00 AM", "Jan 26, 2020 at 12:00 AM", "Feb 2, 2020 at 12:00 AM", "Feb 9, 2020 at 12:00 AM", "Feb 16, 2020 at 12:00 AM"]
答案 1 :(得分:2)
enumerateDates(startingAfter:matching:matchingPolicy:)
Calendar
方法
// Create the date component matching the weekday (Sunday = 1)
let mondayComponent = DateComponents(weekday: 2)
// Calculate Jan 1st of the current date
let calendar = Calendar.current
let currentDate = Date()
var startOfYear = currentDate
var interval : TimeInterval = 0.0
_ = calendar.dateInterval(of:.year, start: &startOfYear, interval: &interval, for: currentDate)
// Get the current year as integer
let thisYear = calendar.component(.year, from: startOfYear)
// Create an array for the result
var allMondays = [Date]()
// If Jan 1st is a Monday append it to the array
if calendar.component(.weekday, from: startOfYear) == 2 { allMondays.append(startOfYear) }
// Now enumerate all dates matching the weekday component within this year
// If the year reaches thisYear + 1 the block will be exited.
calendar.enumerateDates(startingAfter: startOfYear, matching: mondayComponent, matchingPolicy: .nextTime) { (date, strict, stop) in
guard let date = date else { return }
if calendar.component(.year, from: date) > thisYear {
stop = true
} else {
allMondays.append(date)
}
}
答案 2 :(得分:1)
你走了。它非常简单,但有一些问题,特别是NSCalendarOptions
的optionSets,dateByAddingComponents
返回一个可选项,NSCalendarUnit
的枚举名称更改和弃用是NSDateComponents.week
,但其他方面很简单。我没有检查逻辑......
//NSDate *pickerDate = [NSDate date];
let pickerDate = NSDate() /* I just used today for playground */
//NSLog(@"pickerDate: %@", pickerDate);
print("pickerDate: \(pickerDate)")
//NSDateComponents *dateComponents;
var dateComponents: NSDateComponents /* var because you keep reallocating it */
//NSCalendar *calendar = [NSCalendar currentCalendar];
let calendar = NSCalendar.currentCalendar()
//dateComponents = [calendar components:NSWeekdayCalendarUnit fromDate:pickerDate];
dateComponents = calendar.components(NSCalendarUnit.Weekday, fromDate: pickerDate)
//NSInteger firstMondayOrdinal = 9 - [dateComponents weekday];
let firstMondayOrdinal = 9 - dateComponents.weekday
//dateComponents = [[NSDateComponents alloc] init];
dateComponents = NSDateComponents()
//[dateComponents setDay:firstMondayOrdinal];
dateComponents.day = firstMondayOrdinal
//NSDate *firstMondayDate = [calendar dateByAddingComponents:dateComponents toDate:pickerDate options:0];
if let firstMondayDate = calendar.dateByAddingComponents(dateComponents, toDate: pickerDate, options: NSCalendarOptions(rawValue: 0)) {
/* this returns an optional so test for it */
//dateComponents = [[NSDateComponents alloc] init];
dateComponents = NSDateComponents()
//[dateComponents setWeek:1]; /* week deprecated */
dateComponents.weekOfYear = 1 /* this line is redundant, re-done inside for */
//for (int i=0; i<64; i++) {
for i in 0 ..< 64 {
//[dateComponents setWeek:i];
dateComponents.weekOfYear = i
// NSDate *mondayDate = [calendar dateByAddingComponents:dateComponents toDate:firstMondayDate options:0];
let mondayDate = calendar.dateByAddingComponents(dateComponents, toDate: firstMondayDate, options: NSCalendarOptions(rawValue: 0))
/* no need to test for nil if just printing it, but beware */
//NSLog(@"week#: %i, mondayDate: %@", i, mondayDate);
print("week#: \(i), mondayDate: \(mondayDate)")
}
}
答案 3 :(得分:0)
在这里,我只是自定义了上面的代码,以获取不同数量的周日
此处是从您的约会开始获取下一个星期天的扩展名
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))!
}
var nextSunday: Date {
return Calendar.gregorian.date(byAdding: DateComponents(weekOfYear: 1), to: startOfWeek)!
}
}
//Write this logic in your custom function
@objc func getNext100Sundsays(){
let firstSunday = date?.nextSunday
var result = [firstSunday]
var displayResult = [String]()
(1...1000).forEach { _ in
guard let nextSunday = result.last??.nextSunday else { return }
let stringDispayDate = displayDateFormatter.string(from: nextSunday)
result.append(nextSunday)
displayResult.append(stringDispayDate)
}
}