Изменение NSDate для представления 1 месяца с сегодняшнего дня

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

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

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


person bmalicoat    schedule 09.10.2008    source источник
comment
Спасибо. У меня такой же вопрос. :-)   -  person Frank V    schedule 15.06.2009


Ответы (5)


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

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

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

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

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];

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

person mmalc    schedule 09.10.2008
comment
Лучше использовать NSDateCompontents и setMonth на +1. Тогда вы получите ту же дату, но в следующем месяце. NSDateComponents *components = [gregorian components: NSYearCalendarUnit|NSMonthCalendarUnit|NSDayCalendarUnit fromDate:[NSDate date]]; [components setMonth://here you set current month+1]; NsDate *nextMonth = [gregorian dateFromComponents:components]; - person lagos; 21.08.2012

Используйте 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 месяц по григорианскому календарю».

person Nick Forge    schedule 05.04.2010
comment
У меня нет устройства для тестирования прямо сейчас, но что произойдет, если вы продвинетесь на один месяц вперед 29 января, если это не високосный год? Будет ли это 28 февраля или 1 марта? - person Jack Humphries; 15.07.2013

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

Получите текущую дату dayOfMonth, monthOfYear и yearOfCommonEra в виде трех чисел.

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

Создайте эту новую дату с помощью initWithYear NSCalendarDate: месяц: день: час: минута: секунда: timeZone:

person Heng-Cheong Leong    schedule 09.10.2008
comment
В документации ясно указано, что NSCalendarDate не следует использовать. - person mmalc; 09.10.2008
comment
использование NSCalendarDate обычно не допускается для приложений iPhone. - person oberbaum; 15.02.2010

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

person Community    schedule 16.02.2009

Вы можете сделать следующее:

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]; 
person Shanmugaraja G    schedule 17.07.2012