Obtenga NSDate de NSDate ajustado con la zona horaria

Tengo un objeto NSDate. Digamos que representa “1-10-2011”

NSDate *date = [df dateFromString:@"2011-10-01 00:00:00"]; 

Esa fecha se traduce en “2011-09-30 22:00:00” debido a mi zona horaria.

Pregunta: ¿Cómo obtengo un nuevo objeto Date que representa “2011-10-01 00:00:00” en mi zona horaria local?

NSDate solo representa un punto absoluto en el tiempo . No tiene ningún concepto de zona horaria o calendario. ¡Cuando creas una instancia de NSDate es solo un número de segundos desde el 1 de enero de 2001 GMT! No importa si estás en Nueva York, Tokio, Barcelona o Jerusalén.

En su ejemplo, instancia el NSDate basado en GMT, pero [date description] (utilizado en NSLog ) lo traduce a su hora local. Ahí tienes el desajuste.

Entonces, hay dos partes a considerar:

1. Creación de NSDate usando NSCalendar y NSTimeZone

Si está creando una fecha manualmente, debe especificar el calendario (2012 en gregoriano, pero 5772 en hebreo) y zona horaria (22PM, hora de Londres, pero 7AM, hora de Sydney).

 // Use the user's current calendar and time zone NSCalendar *calendar = [NSCalendar currentCalendar]; [calendar setTimeZone: [NSTimeZone systemTimeZone]]; // Specify the date components manually (year, month, day, hour, minutes, etc.) NSDateComponents *timeZoneComps=[[NSDateComponents alloc] init]; [timeZoneComps setHour:22]; [timeZoneComps setMinute:0]; [timeZoneComps setSecond:0]; // ... year, month, ... // transform the date compoments into a date, based on current calendar settings NSDate *date = [calendar dateFromComponents:timeZoneComps]; 

En este momento, la fecha almacena el punto exacto en el tiempo (en segundos) que representa el calendario actual.

2. Salida de NSDate usando NSDateFormatter

Para obtener un resultado controlado de su NSDate, necesita NSDateFormatter , que se utiliza para convertir fechas en cadenas.

Basado en la documentación de referencia de clase de Apple NSDateFormatter

Hay muchos atributos que puede obtener y establecer en un formateador de fecha de estilo , … Sin embargo, le recomendamos que no modifique la configuración individual . En su lugar, debe aceptar la configuración predeterminada establecida en la inicialización y especificar el formato utilizando setDateStyle :, setTimeStyle:

Esto es especialmente importante para la salida, que es diferente para cada localidad. Por defecto, NSDateFormatter observa la configuración regional actual del usuario. Entonces, el mismo NSDate podría ser 22.11.2011 18:33:19 , o Nov 22, 2011 6:33:19 PM , o 2011-11-22 下午6:33:19 o incluso २२-११-२०११ ६:३३:१९ अपराह् , todos para la misma entrada y con el mismo código.

Y el código:

 // NSDate *date -> NSString *dateString NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; [dateFormatter setDateStyle:NSDateFormatterMediumStyle]; [dateFormatter setTimeStyle:NSDateFormatterShortStyle]; // Medium style date, short style time => "Nov 23, 1937 3:30pm" NSString *dateString = [dateFormatter stringFromDate:date]; 

O puede transformarlo utilizando el método de clase localizedStringFromDate: dateStyle: timeStyle:

Espero que esto aclare el problema.

[NSDate date] devuelve la fecha en GMT.

Cuando declaras:

Esa fecha se traduce en “2011-09-30 22:00:00” debido a mi zona horaria.

¿ NSLog es de NSLog o NSDateFormatter ? No confíe en [date description] que usa NSLog, toma en cuenta su zona horaria local, use NSDateFormatter . NSDateFormatter tiene un método setTimeZone .

De Apple documentos en [date description] :

No se garantiza que la representación se mantenga constante en las diferentes versiones del sistema operativo. Para formatear una fecha, debe usar un objeto formateador de fecha en su lugar