2012-06-30 15 views
9

Estoy tratando de usar NSDateFormatter en mi aplicación que toma una cadena de fecha y la formatea a NSDate para que pueda hacer comparaciones de fechas, sin embargo, cuando uso dateFromString y la formateo la fecha es perdiendo un diaNSDateFormatter dateFromString devuelve una fecha incorrecta

NSString *dateString = @"02-06-2012"; 
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; 
[dateFormatter setDateFormat:@"dd-MM-yyyy"]; 
NSDate *dateFromString = [[NSDate alloc] init]; 
dateFromString = [dateFormatter dateFromString:dateString]; 
NSLog(@"My Date = %@", dateFromString); 
[dateFormatter release]; 

Esto da salida a la consola:

Mi Fecha = 2012-06-01 23:00:00 +0000

Respuesta

19

I no creas que la respuesta de Dhruv es correcta. De hecho, no está claro si hay algún problema. Parece que tienes una expectativa incorrecta de lo que debería pasar y/o una interpretación de lo que está sucediendo.

NSDate representa un momento en el tiempo. Este momento no tiene un nombre único. Será conocido por diferentes nombres en diferentes lugares y bajo diferentes sistemas de nombres (zonas horarias, calendarios). NSDate no se ocupa de nada de esto, excepto que es poco convincente en su método -description, donde tiene que producir una representación de cadena de ese momento.

En segundo lugar, una cadena como "02-06-2012" no especifica un momento preciso en el tiempo. En primer lugar, es solo una fecha sin información de tiempo, por lo que NSDateFormatter se establece de manera predeterminada en el primer momento para esa fecha. En segundo lugar, no especifica la zona horaria. El primer momento del día calendario es un momento diferente en cada zona horaria. A menos que especifique una zona horaria con -setTimeZone: o la cadena en sí misma contiene información de zona horaria, NSDateFormatter asume que las cadenas de fecha que pida analizar se encuentran en la zona horaria actual.

Por lo tanto, su objeto dateFromString representa el primer momento de la fecha especificada, 02-06-2012, en su zona horaria. Supongo que esto es lo que querías. Sin embargo, luego se confundió por la forma en que NSDate se describe a sí mismo cuando se registra. Como dije, NSDate tiene que elegir un "nombre" (representación de cadena) para el momento en que representa y el nombre que elige es bastante arbitrario. En estos días está eligiendo el nombre por el que se conoce el momento en UTC. De la salida de registro que se muestra en su pregunta, deduzco que se encuentra en UTC + 0100. Por lo tanto, la fecha puede parecerse a la de un día anterior, pero realmente es el mismo momento que usted especificó. En otras palabras, "2012-06-01 23:00:00 +0000" y "2012-06-02 00:00:00 +0100" son dos nombres equivalentes para exactamente el mismo momento en el tiempo. Simplemente no estás acostumbrado a ver el primero y lo malinterpretaste.

La lección es que debe dejar de confiar en la autodescripción de NSDate para estar en cualquier zona horaria en particular. Realmente, no debes confiar en nada al respecto, ya que no está documentado. De hecho, los documentos para -[NSDate description] indican que "no se garantiza que la representación permanezca constante en las distintas versiones del sistema operativo".

solución de Dhruv parece para ayudar simplemente porque causa NSDateFormatter y -[NSDate description] ponerse de acuerdo sobre el huso horario. Pero eso no es confiable. No funcionaría en Snow Leopard, por ejemplo, porque -[NSDate description] usaba la zona horaria local en lugar de UTC en esa versión de los marcos.

Lo que es más importante, sin embargo, altera el momento real representado por el objeto NSDate que obtienes de la interpretación de NSDateFormatter de tu cadena de fecha. Sospecho que realmente quieres que tenga un significado específico, quieres que la cadena se interprete como que está en el huso horario local, y su solución frustra tu intento.

tl; dr: estabas obteniendo la fecha que siempre quisiste; no confíe en -[NSDate description]; no use la solución de Dhruv

+0

Hola Ken, gracias por la respuesta detallada, ¿qué recomendarías que haga o use? En mi aplicación, necesito verificar que sea igual o superior a una fecha codificada rígida específica que necesito poner en mi aplicación. Gracias – MonkeyBlue

+1

Tienes que decidir qué momento realmente quieres decir. ¿La fecha codificada está destinada a ser interpretada como en una zona horaria específica y fija (como la de la oficina central de su empresa)? ¿O se supone que debe interpretarse como que está en la zona horaria del usuario? Si es el primero, debe establecer el huso horario fijo en el formateador de fecha. Si es el último, puede dejarlo como predeterminado o puede establecerlo explícitamente en '[NSTimeZone defaultTimeZone]' (o '+ systemTimeZone'). –

+0

Gracias Ken lo probaré - el tiempo fijo es básicamente una fecha específica, así que si abre la aplicación y su base en cualquier parte del mundo debería usar la fecha específica y ver si hoy es mayor o igual, estamos haciendo esto ya que tenemos que mostrar información diferente en nuestra aplicación desde una fecha determinada. Tu explicación también tiene más sentido, así que marcaré tu respuesta. Gracias – MonkeyBlue

49

Trate de añadir estas líneas a su código,

[dateFormatter setTimeZone:[NSTimeZone timeZoneWithAbbreviation:@"GMT+0:00"]]; 

o

[dateFormatter setTimeZone:[NSTimeZone timeZoneWithName:@"GMT"]]; 

actualización SWIFT:

Código de quetion,

let dateString = "02-06-2012" 
var dateFormatter = NSDateFormatter() 
dateFormatter.dateFormat = "dd-MM-yyyy" 
var dateFromString : NSDate = dateFormatter.dateFromString(dateString)! 
println("My Date \(dateFromString)") 

y solución,

dateFormatter.timeZone = NSTimeZone(name: "GMT") 

O

dateFormatter.timeZone = NSTimeZone(abbreviation: "GMT+0:00") 
+0

Gracias es perfecto. – MonkeyBlue

+0

¿No sería esta una solución no genérica? ¿Qué pasa si el dispositivo no está en GMT? – Stavash

+4

@stavash Ese es el punto, GMT es lo mismo que UTC o Universal Time. Es la zona horaria estandarizada que todos pueden usar y nunca cambia (debido al horario de verano, etc.). Así es como iOS almacena las fechas/horas ... – lnafziger

Cuestiones relacionadas