2011-09-06 8 views
5

Este códigodateFromComponents NSCalendar: GMT zona horaria en lugar de systemTimeZone

NSCalendar *calendar =[NSCalendar currentCalendar]; 
[gregorian setTimeZone:tz]; 

NSLog(@"%@", [gregorian timeZone]); 

NSDateComponents *comp = [gregorian components:(NSYearCalendarUnit | NSMonthCalendarUnit) fromDate:[NSDate date]]; 

[comp setDay:info.day]; 
[comp setMonth:info.month]; 
[comp setYear:info.year]; 
[comp setHour:info.hour]; 
[comp setMinute:info.minute]; 
[comp setSecond:info.second]; 
[comp setTimeZone:tz]; 

NSLog(@"%@", [comp timeZone]); 
NSLog(@"%@", [gregorian dateFromComponents:comp]); 

muestra lo siguiente en la consola:

Europe/Moscow (MSKS) offset 14400 (Daylight) 

Europe/Moscow (MSKS) offset 14400 (Daylight) 

2011-08-31 20:00:00 +0000 

Por lo tanto, la zona horaria para el calendario y los componentes se especifica correctamente, pero [gregorian dateFromComponents:comp] devuelve valor NSDate con la zona horaria incorrecta (GMT).

¿Qué debo corregir para obtener la zona horaria correcta?

+2

Si NSLog un 'NSDate'object directamente, siempre obtendrá su representación GMT. De todos modos, los objetos 'NSDate' no tienen ningún concepto de zonas horarias en absoluto. Representan un instante instantáneo ** absoluto ** medido a partir de una fecha de referencia. Puede obtener diferentes representaciones * legibles para el ser humano * de la fecha para las diferentes zonas horarias usando un 'NSDateFormatter', pero eso, representaciones. – albertamg

+0

Creo que NSDate oculta la zona horaria de la que se deriva en los bits insignificantes de la marca de tiempo. Sin embargo, esto solo está destinado a ser utilizado para [descripción de NSDate] y, en el mejor de los casos, no es confiable. –

+0

Sí, tienes razón, muchachos. Gracias, ahora lo entiendo :) – Mitry

Respuesta

6

La salida que está viendo es perfectamente normal. Si NSLog directamente un objeto NSDate, obtendrá lo que devuelva el método description, que es la representación GMT de la fecha (pero que no está tallada en piedra).

NSDate objetos no están sujetos a zonas horarias. Un NSDate representa un absoluto instante en el tiempo medido a partir de una fecha de referencia. Por ejemplo, al momento de escribir, la fecha actual es algo así como 337035053.199801 (segundos desde la fecha de referencia), que se puede representar como 2011-09-06 20:50:53 GMT o 2011-09-06 22:50:53 CEST. Ambas son diferentes representaciones legibles por humanos de la misma fecha de.

En conclusión, ¿qué necesitas para obtener la zona horaria adecuada? Necesitas utilizar NSDateFormatter para obtener una representación de string de tu NSDate en cualquier zona horaria que desees.

+0

NSDate hace referencia a GMT. – zaph

+1

La fecha de referencia es, de hecho, el primer instante del 1 de enero de 2001, GMT. De todos modos, esto representa el punto en el tiempo cuando comenzamos a contar, es decir, '0.0' y usted puede * expresar * ese punto en el tiempo usando cualquier zona horaria. – albertamg

+0

Y un lugar en el espacio, específicamente una zona horaria. – zaph

1

Esta pregunta aparece con bastante frecuencia y la respuesta es usar un NSDateFormatter para obtener el resultado deseado para el formato de fecha. Actualmente, siempre está impreso con la zona horaria GMT. Aquí está la discusión de la documentación de NSDate:

Discusión
La representación no se garantiza que permanecerá constante a través de diferentes versiones del sistema operativo. Para dar formato a una fecha , se debe utilizar un objeto de fecha formateador lugar (ver NSDateFormatter y Guía de formato de datos)

Cuestiones relacionadas