透過 NSCalendar 取得該月 1 號的星期與天數,計算目標週日的偏移量,即可獲得具體日期。
- (NSDate *)dateForWeekday:(NSInteger)weekday weekOfMonth:(NSInteger)week month:(NSInteger)month year:(NSInteger)year {
NSCalendar *cal = [NSCalendar currentCalendar];
NSDateComponents *comp = [[NSDateComponents alloc] init];
comp.year = year; comp.month = month; comp.day = 1;
NSDate *firstDay = [cal dateFromComponents:comp];
NSDateComponents *firstComp = [cal components:NSCalendarUnitWeekday fromDate:firstDay];
NSInteger firstWeekday = firstComp.weekday; // 1=Sun, 2=Mon...
NSInteger offset;
if (firstWeekday < weekday) offset = (weekday - firstWeekday) + 7 * (week - 1);
else if (firstWeekday > weekday) offset = (7 - firstWeekday + weekday) + 7 * (week - 1);
else offset = 7 * (week - 1);
NSRange dayRange = [cal rangeOfUnit:NSCalendarUnitDay inUnit:NSCalendarUnitMonth forDate:firstDay];
if (offset >= dayRange.length) return nil; // 超過該月天數
NSDateComponents *addComp = [[NSDateComponents alloc] init];
addComp.day = offset;
return [cal dateByAddingComponents:addComp toDate:firstDay options:0];
}
// 2024 年 12 月第 3 個星期一
NSDate *date = [self dateForWeekday:2 weekOfMonth:3 month:12 year:2024];
weekday 依 NSCalendar 定義:1=週日, 2=週一...7=週六。nil。NSCalendarUnit 新語法。