问题
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