NSDateComponents: difference between weekOfYear and weekOfMonth

泄露秘密 提交于 2019-12-23 08:48:30

问题


In my app, I have to set up a weekly reminder so that an alert goes off at the same day/time, a week from now. I have been using NSDateComponenents.week = 1 and adding that to an NSDate, using NSCalendar's dateByAddingComponents:toDate:options: API. It seems that week is now being deprecated in iOS7, and the warning tells me to "Use weekOfMonth or weekOfYear, depending on which you mean". But I can't find much documentation about what either of them means.

Can anyone explain the difference between the two? In a basic test, the two return the same value when added to an NSDate, but I'm sure there is some meaningful difference between the two.


回答1:


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.




回答2:


I've always found that weeks seem to be handled strangely in iOS.

weekOfMonth will be 1, 2, 3, 4 etc...

weekOfYear will be 1 to 52 (I think)

They don't seem to be measurements of duration. Just like 'The 3rd of April' is not a measurement of duration whereas "1 day" is a measurement of duration.

The best way to add one weeks would be...

NSCalendar *calendar = [NSCalendar currentCalendar];

NSDate *currentDate = [NSDate date];
NSDateComponents *comps = [[NSDateComponents alloc] init];
[comps setDay:7];
NSDate *date = [calendar dateByAddingComponents:comps toDate:currentDate  options:0];

EDIT

After a little test I was right.

NSDate *date = [NSDate date];
NSCalendar *calendar = [NSCalendar currentCalendar];
NSDateComponents *comps = [calendar components:NSCalendarUnitWeekOfMonth | NSCalendarUnitWeekOfYear fromDate:date];

Printing description of date:
2014-08-20 08:15:13 +0000

Printing description of comps:
<NSDateComponents: 0xb7753c0>
    Week of Year: 34
    Week of Month: 4



回答3:


The difference is useful if you want to set an event to always happen on "the second Tuesday of the month", for example.

In that case you would want weekOfMonth to be 2.




回答4:


I'm using DateComponents to display a recurring event (eg. every 30 days, every 3 weeks, every 2 months). I wrote an extension:

extension DateComponents {
var frequencyString: String? {
    let formatter = DateComponentsFormatter()
    if let value = self.day, value != 0 {
        formatter.allowedUnits = [.day]
    } else if let value = self.weekOfYear, value != 0 {
        formatter.allowedUnits = [.weekOfYear]
    } else if let value = self.month, value != 0 {
        formatter.allowedUnits = [.month]
    } else {
        formatter.allowedUnits = [.day, .weekOfMonth, .month]
    }
    formatter.unitsStyle = .full
    formatter.maximumUnitCount = 1
    return formatter.string(from: self)
}
}

Then in Playground I did this:

var dateComponents = DateComponents()
dateComponents.weekOfYear = 100
dateComponents.calendar = .current

Surprisingly, for .weekOfYear the frequencyString returned nil. When I changed all .weekOfYear to .weekOfMonth in the extension, it returned correct value of weeks (when getting weekOfMonth).



来源:https://stackoverflow.com/questions/25399256/nsdatecomponents-difference-between-weekofyear-and-weekofmonth

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!