获取基于开始日期和给定周数的周范围



我的开始日期是2020年7月13日,Int表示我选择的周数,在本例中为五周。我想打印这五周的每周范围。预期输出示例:

  1. 7月13日-7月19日
  2. 7月20日-7月26日
  3. 7月27日-8月2日
  4. 8月3日-8月9日
  5. 8月10日-8月16日

使用下面的代码,我可以获得前两周,但是,根据周的输入,周应该会继续打印。

func getRanges() {
let arrWeekDates = rangeString!.getWeekDates() // Get dates of two weeks.
let dateFormat = "MMM dd"
let thisMon = arrWeekDates.thisWeek.first!.toDate(format: dateFormat)
let thisSun = arrWeekDates.thisWeek[arrWeekDates.thisWeek.count - 1].toDate(format: dateFormat)
let nextMon = arrWeekDates.nextWeek.first!.toDate(format: dateFormat)
let nextSun = arrWeekDates.nextWeek[arrWeekDates.nextWeek.count - 1].toDate(format: dateFormat)
print("This Week: (thisMon) - (thisSun)")
print("Next Week: (nextMon) - (nextSun)")

}
extension Date {
func getWeekDates() -> (thisWeek:[Date],nextWeek:[Date]) {
var tuple: (thisWeek:[Date],nextWeek:[Date])
var arrThisWeek: [Date] = []
for i in 0..<7 {
arrThisWeek.append(Calendar.current.date(byAdding: .day, value: i, to: startOfWeek)!)
}
var arrNextWeek: [Date] = []
for i in 1...7 {
arrNextWeek.append(Calendar.current.date(byAdding: .day, value: i, to: arrThisWeek.last!)!)
}
tuple = (thisWeek: arrThisWeek,nextWeek: arrNextWeek)
return tuple
}
var startOfWeek: Date {
let gregorian = Calendar(identifier: .gregorian)
let sunday = gregorian.date(from: gregorian.dateComponents([.yearForWeekOfYear, .weekOfYear], from: self))
return gregorian.date(byAdding: .day, value: 1, to: sunday!)!
}
func toDate(format: String) -> String {
let formatter = DateFormatter()
formatter.dateFormat = format
return formatter.string(from: self)
}
}

我创建了一个函数,该函数以开始日期和周数为参数,并返回周开始日期和结束日期的DateInterval数组

func weeks(from date: Date, duration: Int) -> [DateInterval]? {
let calendar = Calendar.current
//Get date for first day of the week
let diff = calendar.component(.weekday, from: date) - calendar.firstWeekday
guard let firstDate = calendar.date(byAdding: .day, value: -(diff < 0 ? 7 + diff : diff), to: date) else {
return nil
}
//Generate start and end date for the duration 
var weeks = [DateInterval(start: firstDate, end: calendar.date(byAdding: .day, value: 6, to: firstDate)!)]
for week in 1..<duration {
guard let firstDayOfWeek = calendar.date(byAdding: .day, value: 7, to: weeks[week - 1].start),
let lastDayOfWeek = calendar.date(byAdding: .day, value: 6, to: firstDayOfWeek) else { return nil }
weeks.append(DateInterval(start: firstDayOfWeek, end: lastDayOfWeek))
}
return weeks
}

使用它并打印日期,您可以进行

if let weeks = weeks(from: Date(), duration: 5) {
let formatter = DateFormatter()
formatter.dateFormat = "MMMM dd"
for interval in weeks {
print("(formatter.string(from: interval.start)) -  (formatter.string(from: interval.end))")
}
}

输出

7月13日-7月19日
7月20日-7月26日
7月27日-8月02日
1月03日-8月09日
2月10日-8月16日

最近我的需求是从给定的日期开始获得一系列的周数,因此,我在@joakim-danielson answer中进行了一些更改,并根据我的要求开发了一个代码。

var startDateString = "01/10/2022"
var endDateString = "31/03/2023"
var df = DateFormatter()
df.dateFormat = "dd/MM/yyyy"
let startDate = df.date(from: startDateString)!
let endDate = df.date(from: endDateString)!
func weeks(from date: Date, toDate: Date) -> [DateInterval]? {
let calendar = Calendar.current
let diff = calendar.component(.weekday, from: date) - calendar.firstWeekday
guard let firstDate = calendar.date(byAdding: .day, value: -(diff < 0 ? 7 + diff : diff), to: date) else {
return nil
}
let sunday = Calendar.current.date(from: Calendar.current.dateComponents([.yearForWeekOfYear, .weekOfYear], from: toDate))
let startDateOfWeek = Calendar.current.date(byAdding: .day, value: 1, to: sunday!)

var weeks = [DateInterval(start: firstDate, end: calendar.date(byAdding: .day, value: 6, to: firstDate)!)]

var actualFirstDate = Date()
var i: Int = 1

repeat {
guard let firstDayOfWeek = calendar.date(byAdding: .day, value: 7, to: weeks[i - 1].start),
let lastDayOfWeek = calendar.date(byAdding: .day, value: 6, to: firstDayOfWeek) else { return nil }
weeks.append(DateInterval(start: firstDayOfWeek, end: lastDayOfWeek))
actualFirstDate = Calendar.current.date(byAdding: .day, value: 1, to: firstDayOfWeek)!
i += 1
} while startDateOfWeek != actualFirstDate

return weeks
}
if let weeks = weeks(from: startDate, toDate: endDate) {
let formatter = DateFormatter()
formatter.dateFormat = "dd/MM/yyyy"
for interval in weeks {
print("(formatter.string(from: interval.start)) - (formatter.string(from: interval.end))")
}
}

输出:

2022年9月25日-2022年10月1日
2022年10月2日-2022年10月15日
1022年11月16日-222年10月23日-29年10日
3022年9月30日-05/11日
2022年11月6日-12/11日
2022年11日-13/11日-19/11日
2022年11月20日-26年11日04/2022 2022年12月-2022年10月12日
2022年11月12日-2022年12日17日
1022年12月18日-20222022年12月31日
2023年1月1日-2023年1月7日
2023年8月1日至2023年01月14日
15/2023年01月21日
2023年02月22日-2023
293年01月29日-2023年02月04日
0023年02月05日-2023-11/02/2023
12/2023年2月12日-2023-18/02/2023
29/2023年03月25日
2023年3月5日-2023年3月11日
2923年3日12日-2023
2723年3年3日19日-2023/03月25日
2023/03年3月26日-2023-04月01日

最新更新