Swift - NSDate and last week of year

后端 未结 1 871
后悔当初
后悔当初 2021-01-24 12:09

I am making a TimeTable app, and i have a method that adds 1 week to the current date, this works as it is supposed to, however if the week transitions from December to January,

相关标签:
1条回答
  • 2021-01-24 12:48

    That dateAtWeekStart() method simply does not work. [.YearForWeekOfYear, .WeekOfYear] are sufficient as calendar units to determine the (start of a) week uniquely. The additional units can make the calculation undetermined. Also you can not just set components.weekday = 1 because in some regions Monday (2) is the first day of the week.

    So it is actually a bit easier:

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

    This should work in all cases and give the start of the week (at midnight) for the given date. There are also other methods one could use, such as rangeOfUnit().

    If you want Sunday to be considered as the first day of the week instead of using the user's regional settings then you have to set the firstWeekday property of the calendar.

    The code to add days or weeks to a date also looks highly suspicious. The extensions method for Int in the SwiftDate project treats a day as 24*60*60 seconds. This is not correct, because in regions with daylight saving times, a day can have 23 or 25 hours when the clocks are adjusted. The correct way to add one week to a date is to use calendar components again:

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

    Update for 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)!
        }
    }
    
    0 讨论(0)
提交回复
热议问题