Каждый iOS-разработчик рано или поздно сталкивается с классом NSDate (не путать с NSData, будьте внимательны, автоподстановка сразу выбирает именно второй вариант!). Я не буду вдаваться в подробности по начальным сведениям, т.к. в стандартной документации достаточно просто и понятно это все расписано. Речь пойдет о том, как же динамически найти любой день на этой неделе или на любой другой.

Для того, чтобы узнать какой же сегодня день по календарю, нужно уточнить какой именно календарь мы собираемся использовать, ведь существует масса календарей. Не будем утруждать себя примерами японского календаря и объявим наш родной григорианский календарь:

NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];

Итак, у нас есть текущая дата ([NSDate date]) и нужно найти, допустим, четверг следующей недели. В этом нам поможет класс NSDateComponents, с помощью него мы можем «вытащить» значения нашей даты, как-то год, месяц, неделя, день месяца, день недели, часы, минуты, секунды для искомой даты. Остальные не очень часто используемые (по крайней мере мной :) ) компоненты вы можете подсмотреть в описании класса.

NSDate *currentDate = [NSDate date];

NSDateComponents *currentComps = [calendar components:( NSYearCalendarUnit | NSMonthCalendarUnit | NSWeekdayOrdinalCalendarUnit | NSWeekdayCalendarUnit | NSHourCalendarUnit | NSMinuteCalendarUnit) fromDate:currentDate];

В данном случае мы взяли текущую дату и разложили ее на компоненты (они перечислены в скобках через знак | ). Если бы из текущей даты вам не нужны , скажем, минуты, то просто удалите NSMinuteCalendarUnit, а если нужны секунды, то добавьте NSSecondCalendarUnit. Все очень просто! Важно, что вам нужно разложить текущую дату по всем требуемым в новой дате компонентам. То есть если нужен год, то включение NSYearCalendarUnit обязательно (конечно, вы можете вручную установить год с помощью [currentComps setYear:2012], но это уже будет не динамика).

И дальше все еще проще, устанавливаем следующую неделю с помощью:

[currentComps setWeekdayOrdinal:[currentComps weekdayOrdinal]+1];

Обратите внимание, что в США, Канаде и некоторых других странах неделя начинается с воскресенья, а так как Aplle… правильно! Американская компания, то и мы вынуждены в данном случае иметь это ввиду. Я это к тому, что четверг получается пятым днем недели и продолжение кода будет выглядеть так:

[currentComps setWeekday:5];

Все! Собираем компоненты в дату!

NSDate *itemDate = [calendar dateFromComponents:currentComps];

Полный код будет выглядеть так:

NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];

NSDate *currentDate = [NSDate date];

NSDateComponents *currentComps = [calendar components:( NSYearCalendarUnit | NSMonthCalendarUnit | NSWeekdayOrdinalCalendarUnit | NSWeekdayCalendarUnit | NSHourCalendarUnit | NSMinuteCalendarUnit) fromDate:currentDate];

[currentComps setWeekdayOrdinal:[currentComps weekdayOrdinal]+1];

[currentComps setWeekday:5];

NSDate *itemDate = [calendar dateFromComponents:currentComps];

[calendar release];

Не переживайте, если текущая неделя последняя, то выражение [currentComps setWeekdayOrdinal:[currentComps weekdayOrdinal]+1]; будет корректно истолковано и неделя будет установлена на первую неделю следующего месяца. Конечно, в данном случаем вместо месяца и недели можно было бы использовать NSWeekOfYearCalendarUnit, но мне больше нравится так :)

С помощью

NSLog(@"Сегодня %@ n Следующий четверг %@", [NSDate date], itemDate);

можете проверить правильность кода.

На самом деле о NSDate можно говорить много, вариантов масса и кому-то может не понравиться, кто-то может найти другое решение, я лишь зацепил небольшую часть для примера и возможно вернусь в будущем к этой теме, если у читателей будет желание.

Спасибо за внимание!

 

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *