Valor inesperado de NSDate

Estoy tratando de almacenar una hora en una cita. En este caso 1.5 segundos. Guardo la hora en la fecha de esta manera:

NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; [dateFormatter setDateFormat:@"mm:ss.SS"]; [dateFormatter setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0.0]]; NSDate *date1 = [dateFormatter dateFromString:@"00:01.50"]; 

Pero si miro en el área de depuración puedo ver que el valor de date1 se estableció en:

 date1 = (NSDate *) 0x1dd32b30 2000-01-01 01:00:01 CET 

¿Alguien podría decirme por qué sucede esto?

Debido a que hay una gran cantidad de preguntas relacionadas con NSDate en SO y todas tienen el mismo tono, le daré una respuesta más larga, probablemente esto se puede derivar de otras preguntas.

A. Hay un malentendido común, lo que es una fecha: una fecha es un punto en la línea de tiempo. No se trata de horas o minutos, no se trata de días, meses, años, no se trata de zonas horarias.

Es un punto en una línea de tiempo. Período.

(E internamente está representado por un número de coma flotante. ¿Es eso una sorpresa?)

B. Hay otro malentendido común, lo que es una fecha: dos fechas, por lo tanto, puntos en una línea de tiempo, son iguales, si tienen el mismo valor. Esto no quiere decir que tengan la misma representación. Dos veces puede ser igual, incluso su representación es completamente diferente. (Esto es, lo que le sucedió a usted). Para una comparación, no importa, qué zona horaria está en uso, se espera, $ lo que sea. Para una comparación no importa, qué calendario está en uso, esperado o $ lo que sea. Si es 11:11 en Colonia, Alemania (UTC + 1) son las 10:11 en Londres, Inglaterra (UTC + 0). Este es el mismo tiempo.

Una fecha es anterior si está en la línea de tiempo antes de otra fecha.

C. Entonces, ¿qué son estas cosas graciosas como días, meses, zonas horarias, etc.? Dado que fuera de un episodio de Star Trek un tiempo como 26,182,382,303.127373 sería difícil de entender y manejar, los seres humanos comenzaron a dar puntos sobre los nombres graciosos de la línea de tiempo. Estas representaciones no son la fecha. Son representaciones de la fecha. Es el mismo problema con los números. ¿No tienes esta broma?

“Hay 10 tipos de personas: aquellos que entienden los números binarios y los que no”.

El espíritu de la broma es que 10 puede ser el valor de diez, si está escrito en notación decimal o puede ser el valor de dos, escrito en notación binaria. Nadie puede decir qué valor “10” denota a menos que conozca el sistema numérico que se usa para la representación. La mayoría de las personas asume que está en un sistema decimal, por lo que “10” significa diez. Esta es una convención popular. Y esto funciona bien ya que casi todo el mundo adoptó esa convención. Pero: “10” puede denotar dos valores diferentes. Y al revés también: el mismo valor se puede escribir con diferentes “cadenas”: 10 en notación decimal es igual a 1010 en notación binaria (y es igual a “2 + 8”, sqrt (100), … Eso es , por qué está permitido escribir = entre ellos.)

Desafortunadamente (no, realmente no, el tiempo tiene que funcionar localmente de una manera fácil) por un tiempo no hay una convención mundial. Si alguien escribe “11:11”, simplemente no puede decir a qué hora (recuerde, es un punto en la línea de tiempo). Probablemente la persona dice implícitamente que este es el momento en su sistema de calendario en su zona horaria. Pero luego debes saber, en qué lugar del mundo está diciendo eso. Tomando día, mes, etc. en la cuenta, probablemente tenga que saber cuál es su religión, porque incluso en un país, las personas de diferentes religiones usan calendarios diferentes.

Como no existe una convención mundial común, por un lado, y Mac OS se está ejecutando en sistemas informáticos en todo el mundo, no se puede asumir que un tiempo impreso está escrito en una anotación que usted espera.

Por lo tanto, es completamente, eh, no muy inteligente para comparar fechas por cadena. No se comparan las fechas, se comparan las cadenas.

Antes de comparar una hora (incluida la fecha), debe transformar la representación en una hora a la hora “real”. Debe agregar información sobre el calendario, la representación está escrita y la zona horaria (que se incluye en el calendario en Cocoa).

En Cocoa, utiliza instancias de NSDateFormatter, NSCalendar, NSDateComponents para realizar este trabajo. Si permite que NSDateFormatter transforme una representación en una hora y viceversa, debe configurar el calendario. (NSDateFormatter asume que se elige el calendario local, si no se establece uno). Simplemente es imposible que NSDateFormatter realice cualquier trabajo de transformación, si no sabe qué calendario usar. Y es simplemente imposible para ti.

Luego puede hacer algunos cálculos con él, la fecha, la hora, la instancia de NSDate, incluida la comparación y, al menos, tiene que volver a transformarla en una representación legible por humanos utilizando un calendario.

Lo que obtienes y te permite pensar, que es un momento equivocado, es simplemente el momento correcto pero en una representación que no esperabas. (-descripción siempre entrega UTC + 0).

Probar NSLog on date devolverá la fecha solo en formato GMT. Entonces, si desea verificar si está obteniendo la hora o fecha correctas, convierta la fecha a cadena y NSLog.

 NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; [dateFormatter setDateFormat:@"mm:ss.SS"]; [dateFormatter setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0.0]]; NSDate *date1 = [dateFormatter dateFromString:@"00:01.50"]; NSString *dateString = [dateFormatter stringFromDate:date1]; NSlog(@"%@",dateString);