Изменение NSDate для представления 1 месяца с сегодняшнего дня
-
06-07-2019 - |
Вопрос
Я добавляю повторяющиеся события в приложение Cocoa, над которым я работаю. Я повторяю каждый день и неделю хорошо, потому что я могу определить их математически (3600 * 24 * 7 = 1 неделя). Я использую следующий код для изменения даты:
[NSDate dateWithTimeIntervalSinceNow:(3600*24*7*(weeks))]
Я знаю, сколько месяцев прошло с тех пор, как событие было повторено, но я не могу понять, как сделать объект NSDate, который представляет 1 месяц / 3 месяца / 6 месяцев / 9 месяцев в будущем. В идеале я хочу, чтобы пользователь повторял ежемесячно, начиная с 14 октября, и он будет повторяться 14 числа каждого месяца.
Решение
(Почти так же, как и этот вопрос .) р>
Из документации .
Использование 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];
Возможна более прямая или эффективная реализация, но она должна быть точной и должна указывать в правильном направлении.
Другие советы
Используйте NSCalender, NSDateComponents и NSDate:
NSDateComponents *components = [[[NSDateComponents alloc] init] autorelease];
components.month = 1;
NSDate *oneMonthFromNow = [[NSCalendar currentCalendar] dateByAddingComponents:components toDate:[NSDate date] options:0];
Просто установите разные свойства компонентов
, чтобы получить разные периоды времени (например, 3 месяца, 6 месяцев и т. д.).
Примечание. В зависимости от контекста вы можете использовать [[NSCalendar alloc] initWithCalendarIdentifier: NSGregorianCalendar] autorelease]
вместо [NSCalendar currentCalendar]
, если "1 месяц" Вы имеете в виду «1 месяц по григорианскому календарю».
Я, вероятно, буду использовать NSCalendarDate.
Получите текущую дату dayOfMonth, monthOfYear и yearOfCommonEra как три числа.
Добавьте необходимое количество месяцев (1/3/6/9), учитывая 1), существует ли эта дата (например, 31 апреля, 29 февраля в не високосный год) и 2) перенос год.
Создайте эту новую дату с initWithYear: месяц: день: час: минута: секунда: времяZone:
NSCalendarDate больше не поддерживается новым SDK, возникнут проблемы при сборке для распространения.
Вы можете сделать следующее:
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];