Search code examples
iosdateswiftdayofweek

Date from week of year returning date not in week


I have come across a rather strange "bug". When getting a date for a week of a year using this method:

let dates = NSMutableArray()
let cal = NSCalendar.currentCalendar()
cal.firstWeekday = 2
let formatter = NSDateFormatter()
formatter.dateFormat = "ww YYYY"
formatter.calendar = cal
let date = formatter.dateFromString(week as String)
println(date)

The string week is 52 2014, so the expected date would be Monday December 22th, but instead it returns Saturday December 20th, at 23:00. First of all, I thought I'd handled the first day of week by setting the firstWeekday-option of the calendar, but no luck. In addition, the date returned isn't even in week 52.

Just to double check I ran cal.components(NSCalendarUnit.WeekOfYearCalendarUnit, fromDate: date!).weekOfYear to double check I'm not an idiot, and no sir, the week for the date produced is 51, the week before the desired week.

Any idea how I can reach the expected result?


Solution

  • Changing the firstWeekday from 1 to 2 won't change the date, it will change just the First weekday from Sunday to Monday.

    You can do it like this:

    func dateFromWeekOfYear(year:Int, weekOfYear:Int, weekday:Int) -> NSDate {
        return NSCalendar.currentCalendar().dateWithEra(1, yearForWeekOfYear: year, weekOfYear: weekOfYear, weekday: weekday, hour: 0, minute: 0, second: 0, nanosecond: 0)!
    }
    
    let date1 = dateFromWeekOfYear(2014, 52, 1)   // Dec 21, 2014, 12:00 AM
    let date2 = dateFromWeekOfYear(2014, 52, 2)   // Dec 22, 2014, 12:00 AM
    let date3 = dateFromWeekOfYear(2014, 52, 3)   // Dec 23, 2014, 12:00 AM
    

    If dealing with a string and you want to set he Stand Alone local day of week you can do it like this:

    let myDate = "2 52 2014"
    let cal = NSCalendar.currentCalendar()
    let formatter = NSDateFormatter()
    formatter.dateFormat = "c ww Y"
    formatter.calendar = cal
    if let date1 = formatter.dateFromString(myDate) {
        date1  // "Dec 22, 2014, 12:00 AM"
    }
    

    If you need further reference you can use this:

    enter image description here