如何在日期ios数组中获取所有星期日

时间:2015-09-11 07:03:13

标签: ios arrays swift nsdate nscalendar

我只想要一个以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);
    }

4 个答案:

答案 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)
        }
    }