NSDate - Hace un año, el dilema
-
12-10-2019 - |
Pregunta
Estoy tratando de hacer algo que, para mí, es un poco difícil. Pero estoy seguro de que alguien tiene una idea.
Dada una fecha, por ejemplo January 17, 2011
, estoy tratando de averiguar el día que corresponde a esta fecha hace un año. Así January 17, 2011
es un lunes, y hace un año, este día se cayó en January 18, 2010
(un lunes así). Resulta que January 18, 2010
es de 354 días antes de January 17, 2011
. Al principio pensé que simplemente restar los 365 días durante un año no bisiesto y 366 días de un año bisiesto, pero si lo hace que, en este caso, se llega a January 17, 2010
, que es un domingo, no un lunes.
Por lo tanto, en Objective-C con NSDate
y NSCalendar
, ¿cómo podría implementar una función, tales como:
-(NSDate *)logicalOneYearAgo:(NSDate *)from {
}
En otras palabras, el enésimo "día de la semana" del mes de orden n (donde "día de la semana" es el lunes o el martes o el miércoles, etc)
Solución 5
The answer turned out to be pretty simple. It turned out from trial and error. Here's the answer.
if the year is a leap year, subtract 365 days.
if the year is not a leap year, subtract 364 days.
Otros consejos
Se utiliza NSDateComponents este 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];
}
Esto se trata en el Fecha y hora de programación en la sección Guía cálculos de calendario, Adición de componentes a una fecha
Específicamente, el método de interés es dateByAddingComponents : tODATE: opciones
.Usando el ejemplo de Apple como base, para restar un año a partir de la fecha actual, debería hacer lo siguiente:
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];
No puedo garantizar esto es la forma más eficiente, pero podría hacerlo utilizando NSCalendar
y NSDateComponents
. Pase su ejemplo NSDate
en [yourCalendar components:yourComponents fromDate:yourDate]
, reste un año a partir de los componentes, y luego usar [yourCalendar dateFromComponents:yourComp]
.
Lo siento por no proporcionar el código completo, pero ha sido un tiempo desde que he trabajado con esos métodos, y yo no quiero darle código que no va a funcionar.
Restar a 1 año. Luego restar 1 día hasta que terminan el mismo día de la semana que desee.
Cada año, los "días de la semana" se remonta a 1 día, excepto cuando hay un 29no de febrero en el medio, que se remontan 2 días.
Es porque un año es de 52 semanas + 1 día (2 años bisiestos).
Así que si se aplica esta lógica indefinidamente, el resultado final será, año tras año, con un 16 de junio a 24 de mayo.
Si no desea que esto suceda, usted tiene que memorizar alguna parte del año de referencia y la base de su aritmética en él.
Por ejemplo, si el "nuevo" Lunes es de 4 días atrás (porque 3 años han pasado), es posible que prefiera para elegir el Lunes 3 días por delante en el tiempo, a fin de no días indefinidamente restar, año tras año.
Espero que ayuda.