What I need is to get all the dates of an specefic day between two dates.
For example.
Day: Tuesday Beginning date: september 21 2020 End date: february 15 2021
Output: dates of every tuesday among those dates
I'm new in Date operations so I don't quite know how I can achieve this.
Does anyone know? Thanks
You can use calendar method nextDate(after:, matching:, matchingPolicy, repeatedTimePolicy:, direction:)
inside a while loop and add a condition to check if the resulting date is less or equal to the end date:
func nextDate(after date: Date, matching components: DateComponents, matchingPolicy: MatchingPolicy, repeatedTimePolicy: RepeatedTimePolicy = .first, direction: SearchDirection = .forward) -> Date?
var start = DateComponents(calendar: .current, year: 2020, month: 9, day: 21).date!
let end = DateComponents(calendar: .current, year: 2021, month: 2, day: 15).date!
var dates: [Date] = []
while let date = Calendar.current.nextDate(after: start, matching: DateComponents(weekday: 3), matchingPolicy: .strict), date <= end {
dates.append(date)
start = date
}
print(dates)
You can also extend DateInterval
and create a custom method to return all dates between start
and end
dates that matches the date components:
extension DateInterval {
func dates(matching components: DateComponents) -> [Date] {
var start = self.start
var dates: [Date] = []
while let date = Calendar.current.nextDate(after: start, matching: components, matchingPolicy: .strict), date <= end {
dates.append(date)
start = date
}
return dates
}
}
Usage:
let start = DateComponents(calendar: .current, year: 2020, month: 9, day: 21).date!
let end = DateComponents(calendar: .current, year: 2021, month: 2, day: 15).date!
let dateInterval: DateInterval = .init(start: start, end: end)
let tuesdays = dateInterval.dates(matching: .init(weekday: 3))
print(tuesdays)
This will print
[2020-09-22 03:00:00 +0000, 2020-09-29 03:00:00 +0000, 2020-10-06 03:00:00 +0000, 2020-10-13 03:00:00 +0000, 2020-10-20 03:00:00 +0000, 2020-10-27 03:00:00 +0000, 2020-11-03 03:00:00 +0000, 2020-11-10 03:00:00 +0000, 2020-11-17 03:00:00 +0000, 2020-11-24 03:00:00 +0000, 2020-12-01 03:00:00 +0000, 2020-12-08 03:00:00 +0000, 2020-12-15 03:00:00 +0000, 2020-12-22 03:00:00 +0000, 2020-12-29 03:00:00 +0000, 2021-01-05 03:00:00 +0000, 2021-01-12 03:00:00 +0000, 2021-01-19 03:00:00 +0000, 2021-01-26 03:00:00 +0000, 2021-02-02 03:00:00 +0000, 2021-02-09 03:00:00 +0000]
A lot depends on what you have to start with. Do you have the values as Date
or String
?
I prefer to have Date
, but for testing, I started with String
...
let formatter = DateFormatter()
formatter.dateFormat = "yyyy/MM/dd"
guard let startDate = formatter.date(from: "2020/09/21"), let endDate = formatter.date(from: "2021/02/15") else { return [] }
Of course, your inputs may be in a different format so you'll need to compensate for this.
Next, we need to find the next Tuesday from the start date
var calendar = Calendar.current
calendar.firstWeekday = 2 // Make Monday the starting point, don't know if I need to compensate for this, but not taking any risks
var components = DateComponents()
components.weekday = 3 // Look for Tuesdays
guard var date = calendar.nextDate(after: startDate, matching: components, matchingPolicy: .nextTime) else { return [] }
Next, we simply want to increment the date
by 7 days so we can jump to the next Tuesday
var datesOfInterest: [Date] = []
while date < endDate {
datesOfInterest.append(date)
guard date = calendar.date(byAdding: .day, value: 7, to: date) else {
// You might want to consider this to be an error, but I'm
// just going for brevity
return []
}
}
return datesOfInterest
Obviously, this assumes you have a function which returns an array of Date
values.
And just for testing...
let test = DateFormatter()
test.dateFormat = "eeee dd MM yyyy"
print(datesOfInterest.map { test.string(from: $0) }.joined(separator: ", "))
which outputted...
Tuesday 22 09 2020, Tuesday 29 09 2020, Tuesday 06 10 2020, Tuesday 13 10 2020, Tuesday 20 10 2020, Tuesday 27 10 2020, Tuesday 03 11 2020, Tuesday 10 11 2020, Tuesday 17 11 2020, Tuesday 24 11 2020, Tuesday 01 12 2020, Tuesday 08 12 2020, Tuesday 15 12 2020, Tuesday 22 12 2020, Tuesday 29 12 2020, Tuesday 05 01 2021, Tuesday 12 01 2021, Tuesday 19 01 2021, Tuesday 26 01 2021, Tuesday 02 02 2021, Tuesday 09 02 2021
in my testing
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.