0

I'm trying to access all the dates from starting to end of the month with the date and day.

struct DateStore {
    static let shared = DateStore()
    
    func monthDays( for selectedDate: Date) -> [Date] {
        var dates = [Date]()
        // if selectedDate 2020/09/01
        // get dates like  [01 Sep, 02 Sep, 03 Sep, 04 Sep ...30 Sep]
        
        // if selectedDate 2020/08/10
        // get dates like  [01 Aug, 02 Aug, 03 Aug, 04 Aug, ...31 Aug]

        return dates
    }
}
DRN
  • 153
  • 2
  • 12

1 Answers1

5

You can get the range of day in the month, and map the range initializing a new date using the year and month components of the date combined with the day from the range. I am using noon time because not every date starts at 12am:

extension Date {
    func datesInSameMonth(using calendar: Calendar = .current) -> [Date] {
        let year = calendar.component(.year, from: self)
        let month = calendar.component(.month, from: self)
        return calendar.range(of: .day, in: .month, for: self)?.compactMap {
            DateComponents(calendar: calendar, year: year, month: month, day: $0, hour: 12).date
        } ?? []
    }
}

print(Date().datesInSameMonth())  // [2020-09-01 15:00:00 +0000, 2020-09-02 15:00:00 +0000, 2020-09-03 15:00:00 +0000, 2020-09-04 15:00:00 +0000, 2020-09-05 15:00:00 +0000, 2020-09-06 15:00:00 +0000, 2020-09-07 15:00:00 +0000, 2020-09-08 15:00:00 +0000, 2020-09-09 15:00:00 +0000, 2020-09-10 15:00:00 +0000, 2020-09-11 15:00:00 +0000, 2020-09-12 15:00:00 +0000, 2020-09-13 15:00:00 +0000, 2020-09-14 15:00:00 +0000, 2020-09-15 15:00:00 +0000, 2020-09-16 15:00:00 +0000, 2020-09-17 15:00:00 +0000, 2020-09-18 15:00:00 +0000, 2020-09-19 15:00:00 +0000, 2020-09-20 15:00:00 +0000, 2020-09-21 15:00:00 +0000, 2020-09-22 15:00:00 +0000, 2020-09-23 15:00:00 +0000, 2020-09-24 15:00:00 +0000, 2020-09-25 15:00:00 +0000, 2020-09-26 15:00:00 +0000, 2020-09-27 15:00:00 +0000, 2020-09-28 15:00:00 +0000, 2020-09-29 15:00:00 +0000, 2020-09-30 15:00:00 +0000]
Leo Dabus
  • 229,809
  • 59
  • 489
  • 571
  • Nicely done. I had forgotten about `range(of:in:for:)`. Plus I like the way you added year and month properties to Date. – Duncan C Sep 19 '20 at 23:10
  • Of course this extension assumes the current calendar. You might want to add function equivalents for those properties with a `usingCalendar:` parameter that has a default value of `Calendar.current`, so you could call them with other calendars. – Duncan C Sep 19 '20 at 23:10
  • @DuncanC I have done that also in some other posts. We can simply add the calendar parameter and set the default as the current. – Leo Dabus Sep 19 '20 at 23:20
  • @DuncanC https://stackoverflow.com/a/62721361/2303865 – Leo Dabus Sep 19 '20 at 23:36
  • Cool. Did you figure out why the version in your screenshot was returning bad year values? – Duncan C Sep 19 '20 at 23:36
  • @DuncanC I messed up when editing. swapped year and month – Leo Dabus Sep 19 '20 at 23:41
  • @LeoDabus *I am using noon time because not every date starts at 12am* - what do you mean? – pawello2222 Sep 20 '20 at 09:47
  • 2
    This is to avoid having different times if the date is a daylight savings transition date which might return 1am instead of 12am. For time insensitive calendrical calculations you should always use noon time. – Leo Dabus Sep 20 '20 at 12:24