NSDateComponents weekOfYear returns wrong date
weekOfYear
works in conjunction with yearForWeekOfYear
:
let calendar = NSCalendar.currentCalendar()
let components = NSDateComponents()
components.yearForWeekOfYear = 2015
components.weekOfYear = 15
print(calendar.dateFromComponents(components)!)
// 2015-04-05 22:00:00 +0000
Update for Swift 3 and later:
let calendar = Calendar.current
var components = DateComponents()
components.yearForWeekOfYear = 2015
components.weekOfYear = 15
print(calendar.date(from: components)!)
NSCalendar dateFromComponents returns strange date
May this help you..!
Note: I used value for weekday as 1
(for IST it gives me correct date). You can update it according to your timezone.
NSCalendar *calendar = [NSCalendar calendarWithIdentifier:NSCalendarIdentifierGregorian];
[calendar setTimeZone:NSTimeZone.localTimeZone];
NSDate *currentDate = [NSDate date];
NSDateComponents *finalComponents = [calendar components:NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitYear | NSCalendarUnitWeekOfYear | NSCalendarUnitWeekday fromDate:currentDate];
[finalComponents setWeekday: 1];
[finalComponents setYearForWeekOfYear:finalComponents.year]; // Update year dynamically here
NSLog(@"Current Date: %@",currentDate);
NSLog(@"Print Date: %@",[calendar dateFromComponents:finalComponents]);
Current Date: Fri Jan 5 20:00:53 2018
Print Date: Sun Dec 31 20:00:00 2017
Ask me, if you need any further help..!
NSDate returns wrong week Number
According to Apple Developer Technical Support:
27 Dec 2015 is week 52, not week 53. The first day of week 53 in 2015 is 28 Dec.
Regardless, you’re correct that the value returned by your
getWeek()
function does not match ISO 8601. The reason for that is that you’re using NSCalendarIdentifierGregorian rather than NSCalendarIdentifierISO8601. There are /lots/ of different ways to do week-of-year calculations. I can go into the gory details if you’d like, but the ‘take home’ message here is that, if you want ISO 8601 week calculations, you should use NSCalendarIdentifierISO8601.
With that change getWeek()
starts producing results that match ISO 8601. Specifically:
print(self.getWeek(self.dateFromFixedFormatString("2015-12-27 12:34")))
print(self.getWeek(self.dateFromFixedFormatString("2015-12-28 12:34")))
Prints:
- 52
- 53
Assuming:
func dateFromFixedFormatString(dateStr: String) -> NSDate {
let df = NSDateFormatter()
df.locale = NSLocale(localeIdentifier: "en_US_POSIX")
df.dateFormat = "yyyy-MM-dd HH:mm"
return df.dateFromString(dateStr)!
}
func getWeek(today:NSDate) -> Int {
let myCalendar = NSCalendar(calendarIdentifier: NSCalendarIdentifierISO8601)!
let myComponents = myCalendar.components(.WeekOfYear, fromDate: today)
let weekNumber = myComponents.weekOfYear
return weekNumber
}
So anyone stating the GregorianCalendar does not work in my code is correct, and should be using the NSCalendarIdentifierISO8601 specifically. NSCalendar.currentCalendar()
does not automatically get the ISO calendar. (very strange)
NSCalendar return wrong date for previous Monday in first week of next year
There is a much smarter way to do that using nextDateAfterDate
of NSCalendar
. It can search backwards for the match of a single component in this case NSCalendarUnitWeekday == 2
NSDate *date = [NSDate dateWithTimeIntervalSince1970:1483620311.228];
NSLog(@"current date ===> : %@", date);
NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
NSDate *previousMonday = [calendar nextDateAfterDate:date
matchingUnit:NSCalendarUnitWeekday
value:2
options:NSCalendarMatchNextTime | NSCalendarSearchBackwards];
NSLog(@"previousMonday date ===> : %@", previousMonday);
The time zone and locale don't really matter.
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.
NSDateComponents weekOfMonth does not alter weekOfYear
NSDateComponents
is only a simple container for its elements. The magic happens in NSCalendar
's methods that calculate NSDate
objects.
So convert the components to a proper date and than back to an NSDateComponents
.
Since you can't calculate the week of year from a year, month and weekOfMonth (there are usually two week-of-years in one week-of-month) you have to select a day for which to check, for example monday.
Related Topics
What Makes a Property a Computed Property in Swift
How to Use Trailing Closure in If Condition
Launch Sudo Command from MACos App Swift
Swift Switch Statement Considered All Cases of Int, But Compiler Still Display Error
In Swift,There's No Way to Get the Returned Function's Argument Names
Swift: Detecting an Unexpected Nil Value in a Non-Optional at Runtime: Casting as Optional Fails
How to Make a Button Have a Rounded Border in Swift
How to Find Max Value for Double and Float in Swift
How to Build a Swift Package for iOS Over Command Line
Continuously Train Coreml Model After Shipping
How to Call the More Specific Method of Overloading
How to Create Instance Variable and Class Variable of the Same Name
Nsdata Contentsofurl Constructor Returns Nil
Nstimer.Scheduledtimerwithtimeinterval in Swift Playground
Using Delegates on Generic Protocol
Nothing Prints Out in the Console in Command Line Tool Xcode