Работа с NSCalendar для получения следующего первого вторника месяца

Это немного странно, но можно ли использовать NSCalendar (или любой компонент, если на то пошло), чтобы выяснить, какой будет дата следующего «первого вторника месяца»?

Например, сегодня четверг, 25 марта 2010 г. Следующий «первый вторник месяца» будет 6 апреля. Точно так же, если бы я искал следующий «первый вторник месяца» 1 апреля, это все равно было бы 6 апреля.

Как бы вы это сделали?

Большое спасибо!!!!!


person Bjorn S.    schedule 25.03.2010    source источник


Ответы (2)


Приведенный ниже код вычисляет первый вторник данной комбинации месяца/года. Он написан на MacRuby, потому что это то, с чем я только что пробовал, но у вас не должно возникнуть проблем с преобразованием его в правильный Objective-C, это просто другой синтаксис (я люблю MacRuby за быстрое опробование идеи):

dc = NSDateComponents.alloc.init
# Set month to April 2010
dc.setYear 2010
dc.setMonth 4

dc.setWeekday 3 # 1 = Sunday, 2 = Monday, ...
dc.setWeekdayOrdinal 1 # We want the first weekday of the month

cal = NSCalendar.alloc.initWithCalendarIdentifier NSGregorianCalendar
date = cal.dateFromComponents dc
date.description # => "2010-04-06 00:00:00 +0200"

Я оставляю вам возможность определить «следующий первый вторник» по заданной дате: сначала выполните расчет для месяца текущей даты, а если результат в прошлом, сделайте это снова для следующего месяца. Используйте -[NSCalendar components:fromDate:], чтобы получить комбинацию месяца/дня данного NSDate.

person Ole Begemann    schedule 25.03.2010

К сожалению, я не могу проверить недееспособность этого кода, но некоторые должны выглядеть так:

NSDateComponents *components = [[NSDateComponents alloc] init];
[components setWeekday:2]; // Monday
[components setMonth:5]; // May
[components setYear:2008];
[components setWeekdayOrdinal:1]
NSCalendar *gregorian = [[NSCalendar alloc]
                         initWithCalendarIdentifier:NSGregorianCalendar];
NSDate *date = [gregorian dateFromComponents:components];

Образцы и подробную информацию см. в этом руководство

person Victor    schedule 25.03.2010
comment
Спасибо, но это просто жестко кодирует дату. Мне нужно иметь возможность динамически определять дату, которую я ищу... - person Bjorn S.; 25.03.2010
comment
Это не сработает. Вам нужно включить [components setWeekdayOrdinal:1];. - person Ole Begemann; 25.03.2010
comment
Ты прав. Этот код также не содержит собственно вычисления даты, а это всего лишь направление реализации рабочей функции. - person Victor; 25.03.2010