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

StackOverflow https://stackoverflow.com/questions/185780

  •  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]; 
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top