如何在 Swift 5 中获取选定一周的第一天



我有一个 53 周的UIPickerView,我尝试获得选定一周的第一天(星期一)。 但每次我选择一周时,我都会得到错误的年份。 例如,如果我选择比当前周(此时是第 31 周)低一周,那么我将得到 2020 年而不是 2019 年。 如果我选择比当前周大一周的一周(例如 2019 年第 32 周),那么我将得到 2019 年 8 月 4 日 23:00 而不是 2019 年 8 月 5 日。

以下是2019年正确周数的列表: https://www.epochconverter.com/weeks/2019

这是我的小演示:

https://github.com/tygruletz/FirstDayOfSelectedWeek

这是我的代码:

class ViewController: UIViewController {
// Interface Links
@IBOutlet weak var pickerView: UIPickerView!
@IBOutlet weak var firstMondayLabel: UILabel!
// Properties
var weeksArray = [String]()
//-- Get the number of weeks for current year.
var numberOfWeeksInYear: Int {
var calendar = Calendar(identifier: .iso8601)
calendar.firstWeekday = 2
let weekRange = calendar.range(of: .weekOfYear,
in: .year,
for: Date())
return weekRange!.count
}
override func viewDidLoad() {
super.viewDidLoad()
weeksArray = (1...numberOfWeeksInYear).map { "($0)" }
print("Number of weeks in current year: (numberOfWeeksInYear)")
}
}
// Functionality for Next Trailer Inspection Cell
extension ViewController: UIPickerViewDelegate, UIPickerViewDataSource{
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 1
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return weeksArray.count
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
return weeksArray[row]
}
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
let mondayOfSelectedWeek = Date().dateCorrespondingTo(weekNumber: Int(weeksArray[row]) ?? 0)
print("1st monday of week (Int(weeksArray[row]) ?? 0) is: (mondayOfSelectedWeek ?? Date())")
firstMondayLabel.text = "(mondayOfSelectedWeek!)"
}
}
extension Date {
func dateCorrespondingTo(weekNumber: Int) -> Date? {
let thisCalendar = Calendar(identifier: .iso8601)
return thisCalendar.date(bySetting: .weekOfYear, value: weekNumber, of: self)
}
}

dateCorrespondingTo(weekNumber:)函数中,您调用的是依赖于实现date(bySetting:...),目前,当您调用它时,您将日期设置为现在,当您选择过去的一周时,它不会过去,但会计算将来的日期。

您获得 8 月 4 日 23:00 的事实是因为日期是以通用时区计算的,因此由于您的本地日期提前一小时,它会重新计算 UTC 时间,回到您的时区。你真的得到了 8 月 5 日 00:00:00,但采用 UTC。

这是一段代码,将计算一年中一周的星期一(请注意,iso8601 日历将一周的第一天设置为星期日,因此您应该在 DateComponents 中使用数字 2 作为工作日参数)

下面是基于您的代码的示例:

extension Date {
func dateCorrespondingTo(weekNumber: Int) -> Date? {
let thisCalendar = Calendar(identifier: .iso8601)
let year = thisCalendar.component(.year, from: self)
let dateComponents = DateComponents(calendar: thisCalendar, timeZone: TimeZone(abbreviation: "UTC"), hour: 0, minute: 0, second: 0, nanosecond: 0, weekday: 2, weekOfYear: weekNumber, yearForWeekOfYear: year)
return thisCalendar.date(from: dateComponents)
}
}

最新更新