斯威夫特 - NSDate和一年的最后一周

时间:2015-10-08 07:10:25

标签: ios swift nsdate

我正在创建一个TimeTable应用程序,并且我有一个方法可以在当前日期增加1周,这可以按原样运行,但是如果一周从12月过渡到1月,则额外增加1天。

这是我的代码:

func getWeekDates(var date: NSDate) -> [NSDate] {
    var dates: [NSDate] = [NSDate]()
    for var i = 0; i < 5; i++ {
        date = date.dateAtWeekStart() + 1.day - 1.week
        date += i.day
        dates.append(date)
    }
    return dates
}

dateAtWeekStart()

func dateAtWeekStart() -> NSDate {
    let flags : NSCalendarUnit = [NSCalendarUnit.Year,NSCalendarUnit.Month ,
        NSCalendarUnit.WeekOfYear,
        NSCalendarUnit.Weekday]
    let components = NSCalendar.currentCalendar().components(flags, fromDate: self)
    components.weekday = 1 // Sunday
    components.hour = self.hour
    components.minute = self.minute
    components.second = self.second
    return NSCalendar.currentCalendar().dateFromComponents(components)!
}

dateAtWeekStart()是NSDate扩展中的函数)

我添加1天并删除1周的原因是因为dateAtWeekStart返回下一个星期日,例如08-10-2015。dateAtWeekStart()返回11-10-2015。

所以这通常很好,但如果我们以今年为例,2015年12月29日。dateAtWeekStart()将于04-01-2015而不是03-01-2016返回。

顺便说一下,设备上的区域设置为丹麦。

dateAtWeekStart,来自一个名为SwiftDate的助手类,由malcommac制作:https://github.com/malcommac/SwiftDate

更新编辑: 我仍然无法弄清楚如何解决这个问题,我尝试在这样的组件中添加年份:components.year = self.year,但是在返回组件时由于某种原因将年份设置为2014年。

1 个答案:

答案 0 :(得分:4)

dateAtWeekStart()方法根本不起作用。 [.YearForWeekOfYear, .WeekOfYear]足以作为日历单位 唯一地确定(开始)一周。额外的单位可以 计算未定。你也不能只是设置 components.weekday = 1因为在某些地区,星期一(2)是第一个 一周中的某一天。

所以它实际上有点容易:

extension NSDate {
    func dateAtWeekStart() -> NSDate {
        let cal = NSCalendar.currentCalendar()
        // cal.firstWeekday = 1 // If you insist on Sunday being the first day of the week.
        let flags : NSCalendarUnit = [.YearForWeekOfYear, .WeekOfYear]
        let components = cal.components(flags, fromDate: self)
        return cal.dateFromComponents(components)!
    }
}

这应该适用于所有情况,并给出给定日期的一周开始(午夜)。还有其他方法 可以使用,例如rangeOfUnit()

如果您希望星期日被视为一周的第一天 而不是使用用户的区域设置 那么你必须设置日历的firstWeekday属性。

将日期或周数添加到日期的代码也显得非常可疑。 SwiftDate项目中Int的扩展方法对待 每天24 * 60 * 60秒。这是不正确的,因为在地区有 夏令时,每天可以有23或25小时的时钟 调整。将一周添加到日期的正确方法是 再次使用日历组件:

date = cal.dateByAddingUnit(.WeekOfYear, value: 1, toDate: date, options: [])!

Swift 3的更新:

extension Date {
    func dateAtWeekStart() -> Date {
        var cal = Calendar.current
        // cal.firstWeekday = 1 // If you insist on Sunday being the first day of the week.
        let components = cal.dateComponents([.yearForWeekOfYear, .weekOfYear], from: self)
        return cal.date(from: components)!
    }
}