NSDate - un anno fa, dilemma
-
12-10-2019 - |
Domanda
che sto cercando di fare qualcosa che, per me, è un po 'difficile. Ma sono sicuro che qualcuno ha una certa comprensione.
Data una data, dice January 17, 2011
, sto cercando di capire il giorno che corrisponde a questa data un anno fa. Così January 17, 2011
è un Lunedi, e un anno fa, questo giorno è caduta su January 18, 2010
(un Lunedi pure). Si scopre che è January 18, 2010
354 giorni prima January 17, 2011
. Ho inizialmente pensato ad semplicemente sottrarre 365 giorni per un anno non bisestile e 366 giorni per un anno bisestile, ma se lo fai in questo caso, si otterrebbe January 17, 2010
, che è una Domenica, non un Lunedi.
Quindi, in Objective-C con NSDate
e NSCalendar
, come potrei implementare una funzione come ad esempio:
-(NSDate *)logicalOneYearAgo:(NSDate *)from {
}
In altre parole, l'ennesima "giorno della settimana" del mese n-esimo (dove "giorno della settimana" è Lunedi o Martedì o Mercoledì etc)
Soluzione 5
La risposta si è rivelata piuttosto semplice. Si è scoperto da tentativi ed errori. Ecco la risposta.
se l'anno è un anno bisestile, sottrarre 365 giorni.
se l'anno non è un anno bisestile, sottrarre 364 giorni.
Altri suggerimenti
Si utilizza NSDateComponents in questo modo:
- (NSDate *)logicalOneYearAgo:(NSDate *)from {
NSCalendar *gregorian = [[[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar] autorelease];
NSDateComponents *offsetComponents = [[[NSDateComponents alloc] init] autorelease];
[offsetComponents setYear:-1];
return [gregorian dateByAddingComponents:offsetComponents toDate:from options:0];
}
Questo è trattato nel Data e ora Programmazione sezione Guida su calcoli Calendrical, Aggiunta di componenti ad un Data
In particolare, il metodo di interesse è dateByAddingComponents : todate: opzioni
.Utilizzando l'esempio di Apple come base, per sottrarre un anno dalla data corrente, si dovrebbe effettuare le seguenti operazioni:
NSDate *today = [[NSDate alloc] init];
NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
/*
Create a date components to represent the number of years to add to the current date.
In this case, we add -1 to subtract one year.
*/
NSDateComponents *addComponents = [[NSDateComponents alloc] init];
addComponents.year = - 1;
return [calendar dateByAddingComponents:addComponents toDate:today options:0];
Non posso garantire questo è il modo più efficiente, ma si potrebbe fare usando NSCalendar
e NSDateComponents
. Passare l'istanza NSDate
in [yourCalendar components:yourComponents fromDate:yourDate]
, sottrarre un anno dai componenti, e quindi utilizzare [yourCalendar dateFromComponents:yourComp]
.
Ci scusiamo per non aver fornito il codice completo, ma è stato un po 'da quando ho lavorato con quei metodi, e io non voglio dare il codice che non funziona.
Sottrarre di 1 anno. Poi sottrarre 1 giorno fino a quando si finisce lo stesso giorno della settimana che si desidera.
Ogni anno i "giorni della settimana" risale 1 giorno, tranne quando v'è un 29 febbraio in mezzo, tornano 2 giorni.
E 'a causa di un anno è di 52 settimane + 1 giorno (+2 per gli anni bisestili).
Quindi, se si applica questa logica a tempo indeterminato, si finirà, anni dopo anni, con un 16 giugno al 24 maggio.
Se non si desidera che ciò accada, è necessario memorizzare da qualche parte l'anno di riferimento e la base la vostra aritmetica su di esso.
Ad esempio, se il lunedi "nuovo" è di 4 giorni di nuovo (perché sono passati 3 anni), si potrebbe preferire di scegliere il lunedi 3 giorni avanti nel tempo, in modo da non giorni a tempo indeterminato sottrazioni, anni dopo anni.
La speranza aiuta.