Изменение NSDate для представления 1 месяца с сегодняшнего дня
Я добавляю повторяющиеся события в приложение Cocoa, над которым я работаю. Я повторяю каждый день и неделю отлично, потому что я могу определить их математически (3600 * 24 * 7 = 1 неделя). Для изменения даты я использую следующий код:
[NSDate dateWithTimeIntervalSinceNow:(3600*24*7*(weeks))]
Я знаю, сколько месяцев прошло с момента повторения события, но я не могу понять, как создать объект NSDate, который представляет собой 1 месяц /3 месяца/6 месяцев /9 месяцев в будущем. В идеале я хочу, чтобы пользователь произносил повтор, начиная с 14 октября, и он повторял 14 числа каждого месяца.
Ответы
Ответ 1
(Почти так же, как этот вопрос.)
Из documentation:
Использование 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];
Возможно, существует более прямая или эффективная реализация, но это должно быть точным и должно указывать в правильном направлении.
Ответ 2
Используйте 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 месяц в григорианском календаре".
Ответ 3
Я, вероятно, буду использовать NSCalendarDate.
Получить текущую дату dateOfMonth, monthOfYear и yearOfCommonEra, как три числа.
Добавьте необходимое количество месяцев (1/3/6/9), соблюдая 1) существует ли эта дата (например, 31 апреля, 29 февраля в течение несезонного года) и 2) перевертывание год.
Создайте эту новую дату с помощью NSCalendarDate initWithYear: month: day: hour: minute: second: timeZone:
Ответ 4
NSCalendarDate больше не поддерживается новым SDK, будет возникать проблема при создании для распространения.
Ответ 5
Вы можете сделать следующее:
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];