How to Make an Array of the Current Week Dates Swift

How to make an array of the current week dates Swift

You can get today's yearForWeekOfYear and weekOfYear calendar components and construct a new date from it. It will give you the first day of the week. If you want your week to start from Monday you need to use iso8601 calendar, if you would like to have your week to start on Sunday you can use Gregorian calendar. To avoid some extreme cases you should do all your calendrical calculations using noon time. Not all dates starts at midnight.

let dateComponents = Calendar(identifier: .gregorian).dateComponents([.yearForWeekOfYear, .weekOfYear], from: Date())
let startOfWeek = Calendar(identifier: .gregorian).date(from: dateComponents)!
let startOfWeekNoon = Calendar(identifier: .gregorian).date(bySettingHour: 12, minute: 0, second: 0, of: startOfWeek)!
let weekDays = (0...6).map { Calendar(identifier: .gregorian).date(byAdding: .day, value: $0, to: startOfWeekNoon)! }
weekDays // ["Jun 7, 2020 at 12:00 PM", "Jun 8, 2020 at 12:00 PM", "Jun 9, 2020 at 12:00 PM", "Jun 10, 2020 at 12:00 PM", "Jun 11, 2020 at 12:00 PM", "Jun 12, 2020 at 12:00 PM", "Jun 13, 2020 at 12:00 PM"]

Expanding on that you can extend Date and create some helpers:

extension Calendar {
static let iso8601 = Calendar(identifier: .iso8601)
static let gregorian = Calendar(identifier: .gregorian)
}

extension Date {
func byAdding(component: Calendar.Component, value: Int, wrappingComponents: Bool = false, using calendar: Calendar = .current) -> Date? {
calendar.date(byAdding: component, value: value, to: self, wrappingComponents: wrappingComponents)
}
func dateComponents(_ components: Set<Calendar.Component>, using calendar: Calendar = .current) -> DateComponents {
calendar.dateComponents(components, from: self)
}
func startOfWeek(using calendar: Calendar = .current) -> Date {
calendar.date(from: dateComponents([.yearForWeekOfYear, .weekOfYear], using: calendar))!
}
var noon: Date {
Calendar.current.date(bySettingHour: 12, minute: 0, second: 0, of: self)!
}
func daysOfWeek(using calendar: Calendar = .current) -> [Date] {
let startOfWeek = self.startOfWeek(using: calendar).noon
return (0...6).map { startOfWeek.byAdding(component: .day, value: $0, using: calendar)! }
}
}

usage:

// this will give you all days of the current week starting monday
Date().daysOfWeek(using: .iso8601) // ["Jun 8, 2020 at 12:00 PM", "Jun 9, 2020 at 12:00 PM", "Jun 10, 2020 at 12:00 PM", "Jun 11, 2020 at 12:00 PM", "Jun 12, 2020 at 12:00 PM", "Jun 13, 2020 at 12:00 PM", "Jun 14, 2020 at 12:00 PM"]
// this will give you all days of the current week starting sunday
Date().daysOfWeek(using: .gregorian) // ["Jun 7, 2020 at 12:00 PM", "Jun 8, 2020 at 12:00 PM", "Jun 9, 2020 at 12:00 PM", "Jun 10, 2020 at 12:00 PM", "Jun 11, 2020 at 12:00 PM", "Jun 12, 2020 at 12:00 PM", "Jun 13, 2020 at 12:00 PM"]

To convert your date to a fixed date format you can create a custom date formatter extending Formatter and Date:

extension Formatter {
static let ddMMyyyy: DateFormatter = {
let dateFormatter = DateFormatter()
dateFormatter.calendar = Calendar(identifier: .iso8601)
dateFormatter.locale = .init(identifier: "en_US_POSIX")
dateFormatter.dateFormat = "dd.MM.yyyy"
return dateFormatter
}()
}

extension Date {
var ddMMyyyy: String { Formatter.ddMMyyyy.string(from: self) }
}

Now you can simply map your dates using the KeyPath:

Date().daysOfWeek(using: .gregorian).map(\.ddMMyyyy) // ["07.06.2020", "08.06.2020", "09.06.2020", "10.06.2020", "11.06.2020", "12.06.2020", "13.06.2020"]

Get an Array of Dates of the current week starting on Monday

You just need to get the first day of the week using iso8601 calendar where the first weekday is Monday and add from 0 to 6 days to it. Try like this:

extension Calendar {
static let iso8601 = Calendar(identifier: .iso8601)
}
extension Date {
var startOfWeek: Date {
return Calendar.iso8601.date(from: Calendar.iso8601.dateComponents([.yearForWeekOfYear, .weekOfYear], from: self))!
}
var daysOfWeek: [Date] {
let startOfWeek = self.startOfWeek
return (0...6).compactMap{ Calendar.current.date(byAdding: .day, value: $0, to: startOfWeek)}
}
}

Date().daysOfWeek  // ["Aug 13, 2018 at 12:00 AM", "Aug 14, 2018 at 12:00 AM", "Aug 15, 2018 at 12:00 AM", "Aug 16, 2018 at 12:00 AM", "Aug 17, 2018 at 12:00 AM", "Aug 18, 2018 at 12:00 AM", "Aug 19, 2018 at 12:00 AM"]

How to get all days in current week in swift

To get the weekdays of the week, it is:

let calendar = Calendar.current
let today = calendar.startOfDay(for: Date())
let dayOfWeek = calendar.component(.weekday, from: today)
let days = calendar.range(of: .weekday, in: .weekOfYear, for: today)!
.compactMap { calendar.date(byAdding: .day, value: $0 - dayOfWeek, to: today) }
.filter { !calendar.isDateInWeekend($0) }

To display that as "Thursday = 82", it is

let formatter = DateFormatter()
formatter.dateFormat = "eeee' = 'D"
for date in days {
print(formatter.string(from: date))
}

Or

let strings = days.map { formatter.string(from: $0) }

Get array of dates for hours, days, weeks, months between current date/time and end date/time

This is what I went with - stuck with "the loop" :S

func monthsInYear() {
print()
print("monthsInYear")

var calendar = Calendar.current
let date = Date()
let monthsOfYearRange = calendar.range(of: .month, in: .year, for: date)
//print(monthsOfYearRange as Any)

if let monthsOfYearRange = monthsOfYearRange {
let year = calendar.component(.year, from: date)

for monthOfYear in (monthsOfYearRange.lowerBound..<monthsOfYearRange.upperBound) {
let components = DateComponents(year: year, month: monthOfYear)
guard let date = Calendar.current.date(from: components) else { continue }
print(date.description(with: Locale.current))
}
}
}

func weeksInMonths() {
print()
print("weeksInMonths")

var calendar = Calendar.current
let date = Date()
let weekOfYearRange = calendar.range(of: .weekOfYear, in: .month, for: date)
//print(weekOfYearRange as Any)

if let weekOfYearRange = weekOfYearRange {
let year = calendar.component(.year, from: date)

for weekOfYear in (weekOfYearRange.lowerBound..<weekOfYearRange.upperBound) {
let components = DateComponents(weekOfYear: weekOfYear, yearForWeekOfYear: year)
guard let date = Calendar.current.date(from: components) else { continue }
print(date.description(with: Locale.current))
}
}
}

func daysInWeek() {
print()
print("daysInWeek")

var calendar = Calendar.current
let date = Date()
let daysInWeekRange = calendar.range(of: .day, in: .weekOfMonth, for: date)
//print(daysInWeekRange as Any)

if let daysInWeekRange = daysInWeekRange {
let year = calendar.component(.year, from: date)
let month = calendar.component(.month, from: date)
let weekOfMonth = calendar.component(.weekOfMonth, from: date)

for dayOfWeek in (daysInWeekRange.lowerBound..<daysInWeekRange.upperBound) {
let components = DateComponents(month: month, day: dayOfWeek, weekOfMonth: weekOfMonth)
guard let date = Calendar.current.date(from: components) else { continue }
print(date.description(with: Locale.current))
}
}
}

func hoursInDay() {
print()
print("hoursInDay")

var calendar = Calendar.current
let date = Date()
let hoursInDayRange = calendar.range(of: .hour, in: .day, for: date)
//print(hoursInDayRange as Any)

if let hoursInDayRange = hoursInDayRange {
let year = calendar.component(.year, from: date)
let month = calendar.component(.month, from: date)
let weekOfMonth = calendar.component(.weekOfMonth, from: date)
let day = calendar.component(.day, from: date)

for hourOfDay in (hoursInDayRange.lowerBound..<hoursInDayRange.upperBound) {
let components = DateComponents(year: year, month: month, day: day, hour: hourOfDay, weekOfMonth: weekOfMonth)
guard let date = Calendar.current.date(from: components) else { continue }
print(date.description(with: Locale.current))
}
}
}

Which produces the following output when run:

monthsInYear
Sunday, January 1, 2017 at 12:00:00 AM Eastern Standard Time
Wednesday, February 1, 2017 at 12:00:00 AM Eastern Standard Time
Wednesday, March 1, 2017 at 12:00:00 AM Eastern Standard Time
Saturday, April 1, 2017 at 12:00:00 AM Eastern Daylight Time
Monday, May 1, 2017 at 12:00:00 AM Eastern Daylight Time
Thursday, June 1, 2017 at 12:00:00 AM Eastern Daylight Time
Saturday, July 1, 2017 at 12:00:00 AM Eastern Daylight Time
Tuesday, August 1, 2017 at 12:00:00 AM Eastern Daylight Time
Friday, September 1, 2017 at 12:00:00 AM Eastern Daylight Time
Sunday, October 1, 2017 at 12:00:00 AM Eastern Daylight Time
Wednesday, November 1, 2017 at 12:00:00 AM Eastern Daylight Time
Friday, December 1, 2017 at 12:00:00 AM Eastern Standard Time

weeksInMonths
Sunday, November 26, 2017 at 12:00:00 AM Eastern Standard Time
Sunday, December 3, 2017 at 12:00:00 AM Eastern Standard Time
Sunday, December 10, 2017 at 12:00:00 AM Eastern Standard Time
Sunday, December 17, 2017 at 12:00:00 AM Eastern Standard Time
Sunday, December 24, 2017 at 12:00:00 AM Eastern Standard Time
Sunday, December 31, 2017 at 12:00:00 AM Eastern Standard Time

daysInWeek
Monday, December 10, 1 at 12:00:00 AM GMT-04:56:02
Tuesday, December 11, 1 at 12:00:00 AM GMT-04:56:02
Wednesday, December 12, 1 at 12:00:00 AM GMT-04:56:02
Thursday, December 13, 1 at 12:00:00 AM GMT-04:56:02
Friday, December 14, 1 at 12:00:00 AM GMT-04:56:02
Saturday, December 15, 1 at 12:00:00 AM GMT-04:56:02
Sunday, December 16, 1 at 12:00:00 AM GMT-04:56:02

hoursInDay
Tuesday, December 12, 2017 at 12:00:00 AM Eastern Standard Time
Tuesday, December 12, 2017 at 1:00:00 AM Eastern Standard Time
Tuesday, December 12, 2017 at 2:00:00 AM Eastern Standard Time
Tuesday, December 12, 2017 at 3:00:00 AM Eastern Standard Time
Tuesday, December 12, 2017 at 4:00:00 AM Eastern Standard Time
Tuesday, December 12, 2017 at 5:00:00 AM Eastern Standard Time
Tuesday, December 12, 2017 at 6:00:00 AM Eastern Standard Time
Tuesday, December 12, 2017 at 7:00:00 AM Eastern Standard Time
Tuesday, December 12, 2017 at 8:00:00 AM Eastern Standard Time
Tuesday, December 12, 2017 at 9:00:00 AM Eastern Standard Time
Tuesday, December 12, 2017 at 10:00:00 AM Eastern Standard Time
Tuesday, December 12, 2017 at 11:00:00 AM Eastern Standard Time
Tuesday, December 12, 2017 at 12:00:00 PM Eastern Standard Time
Tuesday, December 12, 2017 at 1:00:00 PM Eastern Standard Time
Tuesday, December 12, 2017 at 2:00:00 PM Eastern Standard Time
Tuesday, December 12, 2017 at 3:00:00 PM Eastern Standard Time
Tuesday, December 12, 2017 at 4:00:00 PM Eastern Standard Time
Tuesday, December 12, 2017 at 5:00:00 PM Eastern Standard Time
Tuesday, December 12, 2017 at 6:00:00 PM Eastern Standard Time
Tuesday, December 12, 2017 at 7:00:00 PM Eastern Standard Time
Tuesday, December 12, 2017 at 8:00:00 PM Eastern Standard Time
Tuesday, December 12, 2017 at 9:00:00 PM Eastern Standard Time
Tuesday, December 12, 2017 at 10:00:00 PM Eastern Standard Time
Tuesday, December 12, 2017 at 11:00:00 PM Eastern Standard Time

Swift: Creating array of Dates in a swifty way

You were on the right track, you can use map, you just simply need to call it on the range your loop would iterate through.

private func selectWeek(for date: Date) {
if let startOfWeek = date.startOfWeek {
let week = (0...6).compactMap{Calendar.current.date(byAdding: .day, value: $0, to: startOfWeek)}
calendar.selectDates(week)
}
}

How to order an array of diffrent Dates by Weekday in Swift

If you don't care about which week the dates are in and only the days of the week, you can use Dictionary(grouping:by:) to turn the array of dates into a [Int: [Date]]:

func weekDay(of date: Date) -> Int {
return Calendar.current.component(.weekday, from: date)
}
let weekDays = Dictionary(grouping: dates, by: weekDay)
print(weekDays)

For example, weekDays[7] will give you all the dates that are on a Saturday, or nil if there is no dates on Saturday.

Swift - Get next date from a array of weekdays

Never use 86400 for date math, Calendar and IndexSethave powerful methods to do that:

// Put your weekday indexes in an `IndexSet`
let weekdaySet = IndexSet([1, 2, 4, 7]) // Sun, Mon, Wed and Sat

// Get the current calendar and the weekday from today
let calendar = Calendar.current
var weekday = calendar.component(.weekday, from: Date())

// Calculate the next index
if let nextWeekday = weekdaySet.integerGreaterThan(weekday) {
weekday = nextWeekday
} else {
weekday = weekdaySet.first!
}

// Get the next day matching this weekday
let components = DateComponents(weekday: weekday)
calendar.nextDate(after: Date(), matching: components, matchingPolicy: .nextTime)

Get array of dates between today and given date in Swift?

extension Formatter {
static let date: DateFormatter = {
let dateFormatter = DateFormatter()
dateFormatter.calendar = Calendar(identifier: .iso8601)
dateFormatter.locale = Locale(identifier: "en_US_POSIX")
dateFormatter.dateFormat = "yyyy-MM-dd"
return dateFormatter
}()
}

extension Date {
var noon: Date {
return Calendar.current.date(bySettingHour: 12, minute: 0, second: 0, of: self)!
}
}

func dates(for date: String) -> [String] {    
// For calendrical calculations you should use noon time
// So lets get endDate's noon time
guard let endDate = Formatter.date.date(from: date)?.noon else { return [] }
// then lets get today's noon time
var date = Date().noon
var dates: [String] = []
// while date is less than or equal to endDate
while date <= endDate {
// add the formatted date to the array
dates.append( Formatter.date.string(from: date))
// increment the date by one day
date = Calendar.current.date(byAdding: .day, value: 1, to: date)!
}
return dates
}

dates(for: "2019-06-29")  // ["2019-06-25", "2019-06-26", "2019-06-27", "2019-06-28", "2019-06-29"]

How to get weekdays array from system in Swift?

Try these properties:

let fmt = NSDateFormatter()
fmt.weekdaySymbols // -> ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"]
fmt.shortWeekdaySymbols // -> ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]
fmt.veryShortWeekdaySymbols // -> ["S", "M", "T", "W", "T", "F", "S"]
fmt.standaloneWeekdaySymbols // -> ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"]
fmt.shortStandaloneWeekdaySymbols // -> ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]
fmt.veryShortStandaloneWeekdaySymbols // -> ["S", "M", "T", "W", "T", "F", "S"]

It seems they always return Sun ... Sat array regardless .firstWeekday property of the .calendar. So, you have to rotate it manually.

let firstWeekday = 2 // -> Monday

var symbols = fmt.shortWeekdaySymbols
symbols = Array(symbols[firstWeekday-1..<symbols.count]) + symbols[0..<firstWeekday-1]
// -> ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"]


Related Topics



Leave a reply



Submit