How to Get Start and End of the Week in Swift

How to get start and end of the week in swift?

Your code is working perfectly fine. If you would run your code in a Playground, you could see the actual Date objects rather than there String representations. Even if you don't specify a DateFormatter, under the hood, when doing print(Date()), Swift uses a DateFormatter to print Date objects and hence that value will be a relative time instead of the absolute point in time provided by the Date object.

In a Playground you can see that the actual startOfWeek is "Sep 25, 2017 at 12:00 AM", while the endOfWeek is "Oct 1, 2017 at 12:00 AM", which are the correct values for the current week.

Don't use print(Date()) for checking the correctness of Date objects, since as you can see, it will yield unexpected results due to the underlying DateFormatters used.

How do I find the beginning of the week from an NSDate?

you can use Calendar method date(from: DateComponents) passing [.yearForWeekOfYear, .weekOfYear] components from any date it will return the first day of the week from the calendar used. So if you would like to get Sunday just use Gregorian calendar. If you would like to get the Monday as the first day of the week you can use Calendar .iso8601 as you can see in this answer

Xcode 12 • Swift 5.3 or later (works with previous Swift versions as well)

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


extension Date {
func startOfWeek(using calendar: Calendar = .gregorian) -> Date {
calendar.dateComponents([.calendar, .yearForWeekOfYear, .weekOfYear], from: self).date!
}
}

usage:

Date().startOfWeek()  // "Sep 20, 2020 at 12:00 AM"



If you would like to get the beginning of week at a particular timezone you just need to use a custom calendar:

var gregorianUTC = Calendar.gregorian
gregorianUTC.timeZone = TimeZone(identifier: "UTC")!
print(Date().startOfWeek(using: gregorianUTC)) // "2020-09-20 00:00:00 +0000\n"

Current Week Start and End Date

I solve the problem thanks for Support

Code :- it give the current week start and end date.

 NSDate *today = [NSDate date];
NSLog(@"Today date is %@",today);
dateFormat = [[NSDateFormatter alloc] init];
[dateFormat setDateFormat:@"yyyy-MM-dd"];// you can use your format.

//Week Start Date

NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];

NSDateComponents *components = [gregorian components:NSWeekdayCalendarUnit | NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit fromDate:today];

int dayofweek = [[[NSCalendar currentCalendar] components:NSWeekdayCalendarUnit fromDate:today] weekday];// this will give you current day of week

[components setDay:([components day] - ((dayofweek) - 2))];// for beginning of the week.

NSDate *beginningOfWeek = [gregorian dateFromComponents:components];
NSDateFormatter *dateFormat_first = [[NSDateFormatter alloc] init];
[dateFormat_first setDateFormat:@"yyyy-MM-dd"];
dateString2Prev = [dateFormat stringFromDate:beginningOfWeek];

weekstartPrev = [[dateFormat_first dateFromString:dateString2Prev] retain];

NSLog(@"%@",weekstartPrev);


//Week End Date

NSCalendar *gregorianEnd = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];

NSDateComponents *componentsEnd = [gregorianEnd components:NSWeekdayCalendarUnit | NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit fromDate:today];

int Enddayofweek = [[[NSCalendar currentCalendar] components:NSWeekdayCalendarUnit fromDate:today] weekday];// this will give you current day of week

[componentsEnd setDay:([componentsEnd day]+(7-Enddayofweek)+1)];// for end day of the week

NSDate *EndOfWeek = [gregorianEnd dateFromComponents:componentsEnd];
NSDateFormatter *dateFormat_End = [[NSDateFormatter alloc] init];
[dateFormat_End setDateFormat:@"yyyy-MM-dd"];
dateEndPrev = [dateFormat stringFromDate:EndOfWeek];

weekEndPrev = [[dateFormat_End dateFromString:dateEndPrev] retain];
NSLog(@"%@",weekEndPrev);

Start and end date of next week swift

You can use dateInterval(of:start:interval:for:):

let formatter = DateFormatter()
let calendar: Calendar = .current

let now = Date()
let weekFromNow = calendar.date(byAdding: .weekOfYear, value: 1, to: now)!

var start = weekFromNow
var interval: TimeInterval = 0
guard calendar.dateInterval(of: .weekOfYear, start: &start, interval: &interval, for: weekFromNow) else { return }

let end = calendar.date(byAdding: .day, value: -1, to: start.addingTimeInterval(interval))!
// or let end = start.addingTimeInterval(interval - 1)
// or let end = calendar.date(byAdding: .day, value: 6, to: start)!

print(formatter.string(from: start), "-", formatter.string(from: end))

This will honor the “start of week” on your device.

how to get year all weeks start date and end date in swift

You can use the suggested extension in this thread: How to get start and end of the week in swift?
To iterate the weeks, and then just print the value with your desired formatter:

let calendar = Calendar.current
let currentYear = calendar.component(.year, from: Date())
let lastDayOfTheYear = calendar.date(from: DateComponents(year: currentYear, month: 12, day: 31))

var currentDate = calendar.date(from: DateComponents(year: currentYear, month: 1, day: 1))

while currentDate! < lastDayOfTheYear! {
let startDay = currentDate!.startOfWeek!.formatted()
let endDay = currentDate!.endOfWeek!.formatted()
print("\(startDay) - \(endDay)")
currentDate = calendar.date(byAdding: .weekOfYear, value: 1, to: currentDate!)
}

extension Date {
func formatted() -> String {
let formatter = DateFormatter()
formatter.dateStyle = .long
return formatter.string(from: self)
}

var startOfWeek: Date? {
let gregorian = Calendar(identifier: .gregorian)
guard let sunday = gregorian.date(from: gregorian.dateComponents([.yearForWeekOfYear, .weekOfYear], from: self)) else { return nil }
return gregorian.date(byAdding: .day, value: 1, to: sunday)
}

var endOfWeek: Date? {
let gregorian = Calendar(identifier: .gregorian)
guard let sunday = gregorian.date(from: gregorian.dateComponents([.yearForWeekOfYear, .weekOfYear], from: self)) else { return nil }
return gregorian.date(byAdding: .day, value: 7, to: sunday)
}
}

prints:

December 30, 2019 - January 5, 2020
January 6, 2020 - January 12, 2020
...
December 21, 2020 - December 27, 2020
December 28, 2020 - January 3, 2021

Swift - Start day and end day of the week before previous week

Something like this should work:

let cal = NSCalendar.currentCalendar()

let components = NSDateComponents()
components.weekOfYear -= 1

if let date = cal.dateByAddingComponents(components, toDate: NSDate(), options: NSCalendarOptions(0)) {
var beginningOfWeek: NSDate?
var weekDuration = NSTimeInterval()
if cal.rangeOfUnit(.CalendarUnitWeekOfYear, startDate: &beginningOfWeek, interval: &weekDuration, forDate: date) {
let endOfWeek = beginningOfWeek?.dateByAddingTimeInterval(weekDuration)
print(beginningOfWeek) // Optional(2015-02-15 05:00:00 +0000)
print(endOfWeek) // Optional(2015-02-22 05:00:00 +0000)
}
}

Get last week and last month start and end dates

You should use this function to calculate the range of dates, it takes a target date, a calendar component and two inout parameters that will be populated with the date and time interval calculated.

func dateInterval(of component: Calendar.Component, start: inout Date, interval: inout TimeInterval, for date: Date) -> Bool

Here's an example:

let calendar = Calendar.current
let today = Date()

let lastWeek = calendar.date(byAdding: .weekOfYear, value: -1, to: today)
let lastMonth = calendar.date(byAdding: .month, value: -1, to: today)

if let lastWeek = lastWeek {
var startOfLastWeek = Date()
var interval = TimeInterval(0)

calendar.dateInterval(of: .weekOfYear, start: &startOfLastWeek, interval: &interval, for: lastWeek)

let endOfLastWeek = startOfLastWeek.addingTimeInterval(interval)

print(startOfLastWeek)
print(endOfLastWeek)
}

if let lastMonth = lastMonth {
var startOfLastMonth = Date()
var interval = TimeInterval(0)

calendar.dateInterval(of: .month, start: &startOfLastMonth, interval: &interval, for: lastMonth)

let endOfLastMonth = startOfLastMonth.addingTimeInterval(interval)

print(startOfLastMonth)
print(endOfLastMonth)
}

If you need to change the first day of the week you can change it in your calendar like this:

var calendar = Calendar.current
calendar.firstWeekday = 2 // 1 is Sunday, 2 is Monday

Remember that when you print the date print(startOfLastMonth), it is displayed in UTC, if you want the date printed in your timezone you will have to use a DateFormatter.

How to get Monday's date of the current week in swift

I wrote Date extensions to get Date for certain weekday and here is how easy it is to use with Swift 5,

Date.today()                                  // Oct 15, 2019 at 9:21 AM
Date.today().next(.monday) // Oct 21, 2019 at 9:21 AM
Date.today().next(.sunday) // Oct 20, 2019 at 9:21 AM


Date.today().previous(.sunday) // Oct 13, 2019 at 9:21 AM
Date.today().previous(.monday) // Oct 14, 2019 at 9:21 AM

Date.today().previous(.thursday) // Oct 10, 2019 at 9:21 AM
Date.today().next(.thursday) // Oct 17, 2019 at 9:21 AM
Date.today().previous(.thursday,
considerToday: true) // Oct 10, 2019 at 9:21 AM


Date.today().next(.monday)
.next(.sunday)
.next(.thursday) // Oct 31, 2019 at 9:21 AM

And here is Date extension for that,

extension Date {

static func today() -> Date {
return Date()
}

func next(_ weekday: Weekday, considerToday: Bool = false) -> Date {
return get(.next,
weekday,
considerToday: considerToday)
}

func previous(_ weekday: Weekday, considerToday: Bool = false) -> Date {
return get(.previous,
weekday,
considerToday: considerToday)
}

func get(_ direction: SearchDirection,
_ weekDay: Weekday,
considerToday consider: Bool = false) -> Date {

let dayName = weekDay.rawValue

let weekdaysName = getWeekDaysInEnglish().map { $0.lowercased() }

assert(weekdaysName.contains(dayName), "weekday symbol should be in form \(weekdaysName)")

let searchWeekdayIndex = weekdaysName.firstIndex(of: dayName)! + 1

let calendar = Calendar(identifier: .gregorian)

if consider && calendar.component(.weekday, from: self) == searchWeekdayIndex {
return self
}

var nextDateComponent = calendar.dateComponents([.hour, .minute, .second], from: self)
nextDateComponent.weekday = searchWeekdayIndex

let date = calendar.nextDate(after: self,
matching: nextDateComponent,
matchingPolicy: .nextTime,
direction: direction.calendarSearchDirection)

return date!
}

}

// MARK: Helper methods
extension Date {
func getWeekDaysInEnglish() -> [String] {
var calendar = Calendar(identifier: .gregorian)
calendar.locale = Locale(identifier: "en_US_POSIX")
return calendar.weekdaySymbols
}

enum Weekday: String {
case monday, tuesday, wednesday, thursday, friday, saturday, sunday
}

enum SearchDirection {
case next
case previous

var calendarSearchDirection: Calendar.SearchDirection {
switch self {
case .next:
return .forward
case .previous:
return .backward
}
}
}
}


Related Topics



Leave a reply



Submit