Get the first day of week without WeekCalendarUnit
You can use .CalendarUnitWeekOfYear
in combination with.CalendarUnitYearForWeekOfYear
, this should give the intended result:
let currentDateComponents = calendar.components(.CalendarUnitYearForWeekOfYear | .CalendarUnitWeekOfYear , fromDate: date)
let startOfWeek = calendar.dateFromComponents(currentDateComponents)
Alternatively, use rangeOfUnit()
(which I personally find easier to
use):
var startOfWeek : NSDate?
calendar.rangeOfUnit(.CalendarUnitWeekOfYear, startDate: &startOfWeek, interval: nil, forDate: date)
In Swift 2 this has to be changed to
let currentDateComponents = calendar.components([.YearForWeekOfYear, .WeekOfYear ], fromDate: date)
let startOfWeek = calendar.dateFromComponents(currentDateComponents)
and
var startOfWeek : NSDate?
calendar.rangeOfUnit(.WeekOfYear, startDate: &startOfWeek, interval: nil, forDate: date)
get first day of week using Weeknumber in Swift
func getFirstDay(weekNumber:Int)->String?{
let Calendar = NSCalendar(calendarIdentifier: NSCalendarIdentifierGregorian)!
let dayComponent = NSDateComponents()
dayComponent.weekOfYear = weekNumber
dayComponent.weekday = 1
dayComponent.year = 2015
var date = Calendar.dateFromComponents(dayComponent)
if(weekNumber == 1 && Calendar.components(.Month, fromDate: date!).month != 1){
print(Calendar.components(.Month, fromDate: date!).month)
dayComponent.year = 2014
date = Calendar.dateFromComponents(dayComponent)
}
let dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "dd-MM-yyyy"
return String(dateFormatter.stringFromDate(date!))
}
Very rough code what i did so far.
It works for finding the first day of the week ;)!
Date from week of year returning date not in week
Changing the firstWeekday from 1 to 2 won't change the date, it will change just the First weekday from Sunday to Monday.
You can do it like this:
func dateFromWeekOfYear(year:Int, weekOfYear:Int, weekday:Int) -> NSDate {
return NSCalendar.currentCalendar().dateWithEra(1, yearForWeekOfYear: year, weekOfYear: weekOfYear, weekday: weekday, hour: 0, minute: 0, second: 0, nanosecond: 0)!
}
let date1 = dateFromWeekOfYear(2014, 52, 1) // Dec 21, 2014, 12:00 AM
let date2 = dateFromWeekOfYear(2014, 52, 2) // Dec 22, 2014, 12:00 AM
let date3 = dateFromWeekOfYear(2014, 52, 3) // Dec 23, 2014, 12:00 AM
If dealing with a string and you want to set he Stand Alone local day of week you can do it like this:
let myDate = "2 52 2014"
let cal = NSCalendar.currentCalendar()
let formatter = NSDateFormatter()
formatter.dateFormat = "c ww Y"
formatter.calendar = cal
if let date1 = formatter.dateFromString(myDate) {
date1 // "Dec 22, 2014, 12:00 AM"
}
If you need further reference you can use this:
List of Days of this week
Edit: missed that you want a week to always start on a Monday
let gregorian = NSCalendar(calendarIdentifier: NSCalendarIdentifierGregorian)!
let today = gregorian.startOfDayForDate(NSDate())
let startOfWeek: NSDate
if gregorian.component(.Weekday, fromDate: today) == 2 {
// Today is Monday
startOfWeek = today
} else {
// Find the last Monday prior to today
startOfWeek = gregorian.nextDateAfterDate(today, matchingUnit: .Weekday, value: 2, options: [.SearchBackwards, .MatchPreviousTimePreservingSmallerUnits])!
}
Get a Week From a Different Starting Day
You can set the firstWeekday
property of the current calendar to determine
the first day of the week for all calendrical calculations:
let cal = NSCalendar.currentCalendar()
cal.firstWeekday = 5 // 1 == Sunday, 5 == Thursday
Use rangeOfUnit
to determine the start and of the week containing the chosen date:
let chosenDate = ...
var startOfWeek : NSDate? = nil
var lengthOfWeek : NSTimeInterval = 0
cal.rangeOfUnit(.WeekCalendarUnit, startDate: &startOfWeek, interval:&lengthOfWeek, forDate: chosenDate)
var endOfWeek = startOfWeek!.dateByAddingTimeInterval(lengthOfWeek)
Iterate over the dates:
var date = startOfWeek!
let formatter = NSDateFormatter()
formatter.dateFormat = "EEEE, dd.MM.yyyy"
while date.compare(endOfWeek) == NSComparisonResult.OrderedAscending {
println(formatter.stringFromDate(date))
date = cal.dateByAddingUnit(.DayCalendarUnit, value: 1, toDate: date, options: NSCalendarOptions(0))
}
Example output (for today as the chosen date):
Thursday, 31.07.2014
Friday, 01.08.2014
Saturday, 02.08.2014
Sunday, 03.08.2014
Monday, 04.08.2014
Tuesday, 05.08.2014
Wednesday, 06.08.2014
Get day of week using NSDate
What you are looking for (if I understand the question correctly) is NSCalendarUnit.CalendarUnitWeekday
. The corresponding property of NSDateComponents
is weekday
.
Note also that your date format is wrong (the
full specification can be found here: http://unicode.org/reports/tr35/tr35-6.html).
The function can be simplified slightly, using automatic type inference, also you use variables a lot where constants are sufficient.
In addition, the function should return an optional which is nil
for an invalid input string.
Updated code for Swift 3 and later:
func getDayOfWeek(_ today:String) -> Int? {
let formatter = DateFormatter()
formatter.dateFormat = "yyyy-MM-dd"
guard let todayDate = formatter.date(from: today) else { return nil }
let myCalendar = Calendar(identifier: .gregorian)
let weekDay = myCalendar.component(.weekday, from: todayDate)
return weekDay
}
Example:
if let weekday = getDayOfWeek("2014-08-27") {
print(weekday)
} else {
print("bad input")
}
Original answer for Swift 2:
func getDayOfWeek(today:String)->Int? {
let formatter = NSDateFormatter()
formatter.dateFormat = "yyyy-MM-dd"
if let todayDate = formatter.dateFromString(today) {
let myCalendar = NSCalendar(calendarIdentifier: NSCalendarIdentifierGregorian)!
let myComponents = myCalendar.components(.Weekday, fromDate: todayDate)
let weekDay = myComponents.weekday
return weekDay
} else {
return nil
}
}
NSDateComponents: difference between weekOfYear and weekOfMonth
The difference between the two show show the week relative to the month or year.
The second week (weekOfMonth) of February would be the seventh week (weekOfYear) of the year, for example, depending on the year.
As to using date components for adding weeks to a date, it doesn't appear to matter which is used but weekOfYear seems to be preferred on the Internet.
I did some testing in a Swift playground and they always calculated the same value when adding weeks to a date.
NSDateComponents returns wrong weekday
It's all correct. If you look at Apple Documentation.
you can see that 1 is Sunday, 2 - is Monday and so forth. So 5 is Thursday as expected.
Error extra argument in call when passing argument to method
Try this:
let now = NSDate()
var startDate: NSDate? = nil
var duration: NSTimeInterval = 0
let cal = NSCalendar.currentCalendar()
cal.rangeOfUnit(NSCalendarUnit.WeekCalendarUnit, startDate: &startDate,
interval: &duration, forDate: now)
(By default, the first parameter has no external name and thus should not be named.)
Related Topics
Pattern Matching in a Swift for Loop
Diffrence Between Function and Generic Function in Swift
Why Do Two Distinct Array Literals Equal Each Other in Swift
In Swift, Can One Use a String to Access a Struct Property
Swift Delegate Beetween Two Vc Without Segue
In Swift, How to Wait Until a Server Response Is Received Before I Proceed
Swift 1.2 Not Working with Same Function Name and Different Parameter
Why Is There a "Plus" Icon at the Top Right Corner of My View
Dynamic Datasource/Delegates for Uitableview in Swift
Cannot Convert Value of Type 'Binding<String>' to Expected Argument Type 'Binding<String>'
Why Does Realm Use Realmoptional<Int> Rather Than Int? for Optional Properties
Can Not Cast Value of Type Nstaggedpointerstring to Nsdictionary
Extending a Protocol Where Self: Generic Type in Swift (Requires Arguments in <...>)
Why Do We Need to Set Delegate to Self? Why Isn't It Defaulted by the Compiler