【发布时间】:2012-12-18 07:40:03
【问题描述】:
有没有更好的方法来确定给定年份的阵亡将士纪念日(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 日。
谢谢,Martin 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] ;
【问题讨论】:
-
我没有检查你的算法,但我想它会归结为大致那么复杂的东西。人们可能会分享一些计算劳动节、感恩节、Birthington 的洗衣日等的逻辑。
-
劳动节、感恩节和总统日都比较简单,因为它们的
weekOfMonths 是普通的整数,而阵亡将士纪念日则取决于一个月中有多少个星期一。太糟糕了... -
但是您仍然可以使用通用逻辑进行大部分计算。或者您可以作弊并要求 5 月的第 5 个星期一,如果计算不畅,则退回到第 4 个。
-
啊,你是对的。
weekOfMonth不像我想的那样工作,所以它不能很容易地计算劳动节、感恩节或总统节。我需要一些共享的逻辑来弄清楚这四个;我会再做一些实验。 -
Birthington 的洗衣日怎么样?
标签: xcode macos cocoa nsdate nsdatecomponents