Domanda

Sto aggiungendo eventi ricorrenti a un'app Cocoa su cui sto lavorando. Ho ripetuto bene ogni giorno e settimana perché posso definirli matematicamente (3600 * 24 * 7 = 1 settimana). Uso il seguente codice per modificare la data:

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

So quanti mesi sono trascorsi da quando l'evento si è ripetuto, ma non riesco a capire come creare un oggetto NSDate che rappresenti 1 mese / 3 mesi / 6 mesi / 9 mesi nel futuro. Idealmente, vorrei che l'utente dicesse di ripetere mensilmente a partire dal 14 ottobre e si ripeterà il 14 di ogni mese.

È stato utile?

Soluzione

(Quasi uguale a questa domanda .)

Dalla documentazione :

  

Uso di NSCalendarDate fortemente   scoraggiato. Non è ancora deprecato,   tuttavia, potrebbe trovarsi nel prossimo SO principale   rilascio dopo Mac OS X v10.5. Per   calcoli calendari, dovresti   utilizzare combinazioni adeguate di   NSCalendar, NSDate e   NSDateComponents, come descritto in   Calendari in Date e orari   Argomenti di programmazione per Cocoa .

Seguendo tale consiglio:

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

Potrebbe esserci un'implementazione più diretta o efficiente, ma questo dovrebbe essere accurato e dovrebbe puntare nella giusta direzione.

Altri suggerimenti

Usa NSCalender, NSDateComponents e NSDate:

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

Basta impostare le diverse proprietà dei componenti per ottenere diversi periodi di tempo (ad es. 3 mesi, 6 mesi ecc.)

Nota: a seconda del contesto, è possibile utilizzare [[[NSCalendar alloc] initWithCalendarIdentifier: NSGregorianCalendar] autorelease] anziché [NSCalendar currentCalendar] , se per "1 mese" intendi " 1 mese sul calendario gregoriano " ;.

Probabilmente userò NSCalendarDate.

Ottieni il giorno della data corrente di mese, mese di anno e anno di calendario, come tre numeri.

Aggiungi il numero di mesi richiesto (1/3/6/9), tenendo conto di 1) se esiste quella data (ad es. 31 aprile, 29 febbraio in un anno non bisestile) e 2) rinnovo di anno.

Crea quella nuova data con initWithYear di NSCalendarDate: mese: giorno: ora: minuto: secondo: fuso orario:

NSCalendarDate non è più supportato dal nuovo SDK, avrà problemi durante la creazione per la distribuzione.

Puoi fare come di seguito:

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]; 
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top