Modifica NSDate per rappresentare 1 mese da oggi
-
06-07-2019 - |
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.
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];