2012-09-04 39 views
8

Encontré los códigos para calcular la diferencia de días entre dos fechas here.
escribo un método:Obtener el número de días entre dos fechas de NSDate en una zona horaria particular

-(NSInteger)daysWithinEraFromDate:(NSDate *) startDate toDate:(NSDate *) endDate 
{ 
    NSCalendar *gregorian = [[NSCalendar alloc] 
          initWithCalendarIdentifier:NSGregorianCalendar]; 
    NSInteger startDay=[gregorian ordinalityOfUnit:NSDayCalendarUnit 
              inUnit: NSEraCalendarUnit forDate:startDate]; 
    NSInteger endDay=[gregorian ordinalityOfUnit:NSDayCalendarUnit 
              inUnit: NSEraCalendarUnit forDate:endDate]; 
    return endDay-startDay; 
} 

Este método tiene un problema: no se puede considerar la cosa zona horaria. Incluso puedo añadir una línea como la siguiente:

[gregorian setTimeZone:[NSTimeZone localTimeZone]]; 

Mi código de prueba es la siguiente:

NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init]; 
    [dateFormat setDateFormat:@"yyyy-MM-dd HH:mm:ss"]; 
    NSString *strDate = @"2012-09-03 23:00:00"; 
    NSDate *dateStart = [dateFormat dateFromString:strDate]; 
    strDate = @"2012-09-04 01:00:00"; 
    NSDate *dateEnd = [dateFormat dateFromString:strDate]; 
    NSLog(@"Days difference between %@ and %@ is: %d days",[dateFormat stringFromDate:dateStart],[dateFormat stringFromDate:dateEnd],[self daysWithinEraFromDate:dateStart toDate:dateEnd]); 

El resultado es: diferencia

días entre 23:00 2012-09-03 : 00 y 2012-09-04 01:00:00 es: 0 días

Quiero obtener 1 día como resultado por el número de midnig hts entre las dos fechas. Mi zona horaria es GMT +8. Pero este cálculo se basa en GMT, así que obtengo el número de días incorrecto. ¿Hay alguna forma de resolver este problema? Gracias.


Scott Lemmon método puede resolver mi problema. Vuelvo a escribir mi código como este:

-(NSInteger)daysWithinEraFromDate:(NSDate *) startDate toDate:(NSDate *) endDate 
{ 
    NSCalendar *gregorian = [[NSCalendar alloc] 
          initWithCalendarIdentifier:NSGregorianCalendar]; 
    [gregorian setTimeZone:[NSTimeZone localTimeZone]]; 
    NSDate *newDate1 = [startDate dateByAddingTimeInterval:[[NSTimeZone localTimeZone] secondsFromGMT]]; 
    NSDate *newDate2 = [endDate dateByAddingTimeInterval:[[NSTimeZone localTimeZone] secondsFromGMT]]; 

    NSInteger startDay=[gregorian ordinalityOfUnit:NSDayCalendarUnit 
              inUnit: NSEraCalendarUnit forDate:newDate1]; 
    NSInteger endDay=[gregorian ordinalityOfUnit:NSDayCalendarUnit 
              inUnit: NSEraCalendarUnit forDate:newDate2]; 
    return endDay-startDay; 
} 

Respuesta

5

Si el desplazamiento de la zona horaria no funciona, ¿qué tal si solo lo agrega o lo resta manualmente?

En su caso NSDate *newDate = [oldDate dateByAddingTimeInterval:(-8 * 60 * 60)]; para restar sus +8 horas.

O si lo desea encontrar el desplazamiento GMT de forma automática, así entonces simplemente sería NSDate *newDate = [oldDate dateByAddingTimeInterval:(-[[NSTimeZone localTimeZone] secondsFromGMT])

Otro pensamiento: A tal solución más fácil sería simplemente ignorar la información de tiempo completo. Simplemente configúrelo para el mismo número arbitrario para ambas fechas, y siempre que las fechas provengan de la misma zona horaria, siempre obtendrá el número correcto de medias noches entre ellas, independientemente de la compensación GMT.

+0

Hola, gracias por tu respuesta. Solo pensé en ignorar la información del tiempo. He hecho esto en mis códigos. ¡Pero tu primera solución es brillante! Creo que es una forma más precisa de resolver este problema. Lo he intentado en mi código, se los mostraré. – Vigor

3

Lo que realmente quiere es el NSDate método timeIntervalSinceDate:, y tomo ese resultado y si es superior a 0 pero inferior a 86400 (el número de segundos en un día), esa es una día. De lo contrario, divida su resultado entre 86400 y obtendrá el número de días.

La forma en que actualmente tiene su código, solo hay 2 horas entre los dos días y es por eso que está viendo un resultado de 0 y no uno.

Editar - y para determinar si ha ocurrido la medianoche, vamos a probar esta función que acabo de escribir la parte superior de mi cabeza:

- (NSDate *) getMidnightDateFromDate: (NSDate *) originalDate 
{ 
    NSDateComponents *components = [[NSCalendar currentCalendar] components:NSIntegerMax fromDate:originalDate]; 
    [components setHour:0]; 
    [components setMinute:0]; 
    [components setSecond:0]; 
    NSDate *midnight = [[NSCalendar currentCalendar] dateFromComponents:components]; 
    return(midnight); 
} 

- (BOOL) howManyDaysDifferenceBetween: startDate and: endDate 
{ 
    NSDate * firstMidnight = [self getMidnightDateFromDate: startDate]; 
    NSDate * secondMidnight = [self getMidnightDateFromDate: endDate]; 
    NSTimeInterval timeBetween = [firstMidnight timeIntervalSinceDate: secondMidnight]; 

    NSInteger numberOfDays = (timeBetween/86400); 

    return(numberOfDays); 
} 

la que estoy basando fuera Dave Delong's answer to this question. No hay garantías de que mi código funcione (no lo probé), pero creo que el concepto es sólido.

+0

Gracias por su respuesta. Deseo determinar si dos instancias de NSDate están en fechas diferentes por el número de noches entre las dos fechas. De acuerdo con su método, todavía obtendré 0 días. Pero 2012-09-03 y 2012-09-04 están en diferentes fechas, aunque el intervalo es de solo 2 horas.Si cambio la segunda fecha al 2012-09-04 08:00:00, recibiré 1 día como resultado de mi método. Creo que es porque la zona horaria. – Vigor

Cuestiones relacionadas