Here is the code:
let components = DateComponents(year: 2022,month: 9,weekOfMonth: 3)
let date = Calendar.autoupdatingCurrent.date(from: components)!
let formatter = DateFormatter()
formatter.dateStyle = .long
formatter.timeStyle = .none
print(formatter.string(from: date))
Here is output:
September 1, 2022
But the correct answer should be September 11, 2022
. Why? Is this a bug or I just missed something?
CodePudding user response:
This method will create a date for start of the given year, month and week in month. This will return nil if the start of the week is not in the month specified:
func startOfWeek(in year: Int, month: Int, week: Int, calendar: Calendar = Calendar(identifier: .iso8601)) -> Date?{
//You would need to set this calendar according when your week starts.
//For me it´s monday so I need .iso8601
//For sunday set it to gregorian
var components = DateComponents(calendar: calendar, year: year, month: month, weekOfMonth: week )
//Get the first day of the month. This will probably never fail but....
guard let firstOfMonth = components.date else{
return nil
}
// Handling edge case first of month is start of week
// if the first is a monday and we look for the first return it
let startOfWeek = calendar.dateComponents([.calendar, .yearForWeekOfYear, .weekOfYear], from: firstOfMonth).date
if startOfWeek == firstOfMonth, week == 1{
return firstOfMonth
}
// else just ommit the additional week and move on
else if startOfWeek == firstOfMonth {
components = DateComponents(calendar: calendar, year: year, month: month, weekOfMonth: week)
}
// search for the next date starting at first of month according to components given
return calendar.nextDate(after: firstOfMonth, matching: components, matchingPolicy: .nextTime)
}
Most of the code should be self explanatory.
Testing:
let dates = [(2022, 1, 2), (2022, 2, 1), (2022, 3, 4), (2022, 8, 1), (2022, 9, 1), (2022, 9, 2), (2022, 9, 3), (2022, 9, 4), (2022, 12, 4) , (2021, 11, 5)]
let formatter = DateFormatter()
formatter.dateFormat = "dd MM yyyy"
dates.forEach { year, month, week in
let date = startOfWeek(in: year, month: month, week: week, calendar: Calendar(identifier: .gregorian))
print(date != nil ? formatter.string(from: date!) : "no date found")
}
Output:
02 01 2022
no date found
20 03 2022
no date found
no date found
04 09 2022
11 09 2022 <-- thrid week in september 2022
18 09 2022
18 12 2022
28 11 2021