2

有没有更好的方法来确定给定年份的阵亡将士纪念日(5 月的最后一个星期一)的 NSDate?

NSInteger aGivenYear = 2013 ;

NSCalendar* calendar = [NSCalendar currentCalendar] ;
NSDateComponents* firstMondayInJuneComponents = [NSDateComponents new] ;
firstMondayInJuneComponents.month = 6 ;
// Thanks, Martin R., for pointing out that `weekOfMonth` is wrong for returning the first Monday in June.
firstMondayInJuneComponents.weekOfMonth = 1 ;
firstMondayInJuneComponents.weekday = 2 ; //Monday
firstMondayInJuneComponents.year = aGivenYear ;
NSDate* firstMondayInJune = [calendar dateFromComponents:firstMondayInJuneComponents] ;

NSDateComponents* subtractAWeekComponents = [NSDateComponents new] ;
subtractAWeekComponents.week = 0 ;
NSDate* memorialDay = [calendar dateByAddingComponents:subtractAWeekComponents toDate:firstMondayInJune options:0] ;

编辑

我现在看到,firstMondayInJune在上面的例子中并不适用于所有年份。它返回 2012 年的 5 月 28 日。

谢谢,马丁R。weekdayOrdinal正是我所希望的,它返回了阵亡将士纪念日,代码行数减少了 3 行:

NSInteger aGivenYear = 2013 ;

NSDateComponents* memorialDayComponents = [NSDateComponents new] ;
memorialDayComponents.year = aGivenYear ;
memorialDayComponents.month = 5 ;
memorialDayComponents.weekday = 2 ; //Monday
memorialDayComponents.weekdayOrdinal = -1 ; //The last instance of the specified weekday in the specified month & year.
NSDate* memorialDay = [calendar dateFromComponents:memorialDayComponents] ;
4

2 回答 2

5

要获得一个月中的第一个星期一,请设置weekdayOrdinal = 1而不是weekOfMonth = 1

NSInteger aGivenYear = 2012 ;

NSCalendar* calendar = [NSCalendar currentCalendar] ;
NSDateComponents* firstMondayInJuneComponents = [NSDateComponents new] ;
firstMondayInJuneComponents.month = 6 ;
firstMondayInJuneComponents.weekdayOrdinal = 1 ;
firstMondayInJuneComponents.weekday = 2 ; //Monday
firstMondayInJuneComponents.year = aGivenYear ;
NSDate* firstMondayInJune = [calendar dateFromComponents:firstMondayInJuneComponents] ;
// --> 2012-06-04

NSDateComponents* subtractAWeekComponents = [NSDateComponents new] ;
subtractAWeekComponents.week = -1 ;
NSDate* memorialDay = [calendar dateByAddingComponents:subtractAWeekComponents toDate:firstMondayInJune options:0] ;
// --> 2012-05-28

NSDateComponents文档中:

工作日序数单位表示工作日在下一个较大日历单位(例如月份)中的位置。例如,2是该月第二个星期五的工作日顺序单位。

于 2013-01-03T22:05:32.353 回答
-1

我可能会做的是获取每月第一天的星期几(可能使用 NSDateFormatter),然后计算第一个星期一/星期二/星期四/该月的任何一天的日期,然后添加 (week# - 1 ) x 7 到该日期以获得第 N 个星期一/每月的任何时间。

对于阵亡将士纪念日,您首先要检查第 5 个星期一是否还在 5 月,如果不是则使用第 4 个星期一。(或者登记入住,知道如果阵亡将士纪念日是 31 日,那么第一个星期一必须是 3 日或更早。)

于 2013-01-03T22:02:07.577 回答