斯威夫特 – 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而不是dateAtWeekStart()

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

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

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

那个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)! } }