Изменение NSDate для представления 1 месяца с сегодняшнего дня - PullRequest
16 голосов
/ 09 октября 2008

Я добавляю повторяющиеся события в приложение Cocoa, над которым я работаю. Я повторяю каждый день и неделю хорошо, потому что я могу определить их математически (3600 * 24 * 7 = 1 неделя). Я использую следующий код для изменения даты:

[NSDate dateWithTimeIntervalSinceNow:(3600*24*7*(weeks))]

Я знаю, сколько месяцев прошло с момента повторения события, но я не могу понять, как создать объект NSDate, который представляет 1 месяц / 3 месяца / 6 месяцев / 9 месяцев в будущем. В идеале я хочу, чтобы пользователь повторял ежемесячно, начиная с 14 октября, и он будет повторяться 14 числа каждого месяца.

Ответы [ 5 ]

37 голосов
/ 09 октября 2008

(почти так же, как этот вопрос .)

Из документации :

Использование NSCalendarDate сильно не рекомендуется. Это еще не устарело, Однако это может быть в следующей основной ОС Выпуск после Mac OS X v10.5. За Календарные расчеты, вы должны используйте подходящие комбинации NSCalendar, NSDate и NSDateComponents, как описано в Календари в Даты и время Темы программирования для какао .

Следуя этому совету:

NSDate *today = [NSDate date];

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

NSDateComponents *components = [[NSDateComponents alloc] init];
components.month = 1;
NSDate *nextMonth = [gregorian dateByAddingComponents:components toDate:today options:0];
[components release];

NSDateComponents *nextMonthComponents = [gregorian components:NSYearCalendarUnit | NSMonthCalendarUnit fromDate:nextMonth];

NSDateComponents *todayDayComponents = [gregorian components:NSDayCalendarUnit fromDate:today];

nextMonthComponents.day = todayDayComponents.day;
NSDate *nextMonthDay = [gregorian dateFromComponents:nextMonthComponents];

[gregorian release];

Возможна более прямая или эффективная реализация, но она должна быть точной и указывать в правильном направлении.

22 голосов
/ 05 апреля 2010

Используйте NSCalender, NSDateComponents и NSDate:

NSDateComponents *components = [[[NSDateComponents alloc] init] autorelease];
components.month = 1;
NSDate *oneMonthFromNow = [[NSCalendar currentCalendar] dateByAddingComponents:components toDate:[NSDate date] options:0];

Просто установите различные свойства components, чтобы получить разные периоды времени (например, 3 месяца, 6 месяцев и т. Д.).

Примечание. В зависимости от контекста вы можете использовать [[[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar] autorelease] вместо [NSCalendar currentCalendar], если под «1 месяц» вы подразумеваете «1 месяц по григорианскому календарю».

0 голосов
/ 17 июля 2012

Вы можете сделать, как показано ниже:

NSDate *today = [NSDate date];

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

NSDateComponents *components = [[NSDateComponents alloc] init];
components.month = 1;
NSDate *nextMonth = [gregorian dateByAddingComponents:components toDate:today options:0];
[components release];

NSDateComponents *nextMonthComponents = [gregorian components:NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit fromDate:nextMonth];
NSDate *nextMonthDay = [gregorian dateFromComponents:nextMonthComponents];

[gregorian release]; 
0 голосов
/ 16 февраля 2009

NSCalendarDate больше не поддерживается новым SDK, возникнут проблемы при сборке для распространения.

0 голосов
/ 09 октября 2008

Я, вероятно, буду использовать NSCalendarDate.

Получите три дня: dayOfMonth, monthOfYear и yearOfCommonEra для текущей даты.

Добавьте необходимое количество месяцев (1/3/6/9), учитывая 1), существует ли эта дата (например, 31 апреля, 29 февраля в не високосный год) и 2) перенос год.

Создайте эту новую дату с initWithYear: месяц: день: час: минута: секунда: времяZone:

...