2010-06-22 14 views
26

que tenía el siguiente código de trabajo en el 3.x OSNSDateFormatter volver nula en OS 4.0

NSString *stringDate = @"2010-06-21T20:06:36+00:00"; 
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; 
[dateFormatter setDateFormat:@"yyyy-MM-dd'T'HH:mm:ssZ"]; 
NSDate *theDate = [dateFormatter dateFromString:stringDate]; 
NSLog(@"%@",[dateFormatter stringFromDate:theDate]); 

pero ahora en el nuevo Xcode 3.2.3 bajo el simulador de iOS 4, el Varialble theDate es nula.

He revisado la referencia de clase y no veo nada desaprobado o implementado de manera diferente para iOS4 con estos métodos específicos. ¿Qué dejé afuera?

+0

Parece que si elimino el "+00: 00" del stringDate y luego quito la "Z" de el formato, funcionará correctamente, pero eso no es realmente una opción, ya que los datos dinámicos que obtengo tienen la zona horaria asociada y no quiero tener que extraer esa parte para cada fecha que tengo. Y no puedo encontrar ninguna documentación que diga que la zona horaria ya no es compatible de esta manera. – AtomRiot

+4

Creo que lo descubrí. El formato que me dan es a medio camino entre RFC 822 y GMT. si cambio el "+00: 00" a "+0000", entonces puedo usar la "Z" en mi formato. y si lo cambio a "GMT + 00: 00" entonces puedo usar ZZZZ para obtener los datos correctamente. Parece que algo se ha eliminado para manejar este híbrido, ya que me funcionaba antes con OS 3.x. – AtomRiot

Respuesta

41

descubrí que funciona si lo haces de esta manera (véase más adelante) . La clave es usar el método: - [NSDateFormatter getObjectValue:forString:range:error:]

en lugar de

-[NSDateFormatter dateFromString]

el código completo:

+ (NSDate *)parseRFC3339Date:(NSString *)dateString 
{ 
    NSDateFormatter *rfc3339TimestampFormatterWithTimeZone = [[NSDateFormatter alloc] init]; 
    [rfc3339TimestampFormatterWithTimeZone setLocale:[[[NSLocale alloc] initWithLocaleIdentifier:@"en_US_POSIX"] autorelease]]; 
    [rfc3339TimestampFormatterWithTimeZone setDateFormat:@"yyyy-MM-dd'T'HH:mm:ssZ"]; 

    NSDate *theDate = nil; 
    NSError *error = nil; 
    if (![rfc3339TimestampFormatterWithTimeZone getObjectValue:&theDate forString:dateString range:nil error:&error]) { 
     NSLog(@"Date '%@' could not be parsed: %@", dateString, error); 
    } 

    [rfc3339TimestampFormatterWithTimeZone release]; 
    return theDate; 
} 
+0

Gracias. dateFromString: y getObjectValue: forSting: range: error: se comporta de manera diferente. Este último sí funciona correctamente, mientras que el anterior se ahoga en la misma cuerda (incluido el colon). –

+0

Muchas gracias ...... :) –

+0

Código excelente, gracias. –

0

Me parece bien.

¿Sigue funcionando correctamente en un dispositivo real?

Si es así un informe de error para el simulador, de lo contrario un informe de error para iOS 4.

+0

todavía no puedo probar en un dispositivo, el mío está mal en este momento. Esperaba que fuera solo un problema con el simulador, pero el formato de fecha no parecía ser algo con lo que el simulador tuviese problemas. – AtomRiot

+0

bien, acabo de probar este código en un dispositivo y veo el mismo comportamiento que el simulador. :( – AtomRiot

8

es su dispositivo establece en 24 horas o de 12 horas?

Eso suena como una pregunta insensata, pero acabo de encontrar ese error: el formateador de fechas ajustará su cadena de formato de acuerdo con la configuración regional actual, que incluirá la configuración del formato de hora.

Puede forzar que ignorarlos añadiendo esta línea:

dateFormatter.locale = [[NSLocale alloc] initWithLocaleIdentifier:@"en_US_POSIX"]; 

Espero que ayude.

+1

hmm, no veo que haga ninguna diferencia. Todavía obtengo el valor nulo de la llamada de dateFromString. – AtomRiot

+0

En ese caso, mi respuesta es completamente incorrecta. Lo siento! – deanWombourne

+0

Esto fue un error en los 2.x días. No estoy seguro si todavía está presente ya que terminé analizando la cadena "a mano". –

2

Me encontré con este problema recientemente. Terminé usando el analizador ISO8601 de Peter Hosey. Está disponible aquí: http://boredzo.org/iso8601unparser/

+0

Esto me salvó la vida, gracias. Prefiero usar un analizador específico que retocar la cadena de fecha de entrada. – scalbatty

1

Obtengo el valor de dataFormat @"yyyy'-'MM'-'dd'T'HH':'mm':'ss'+'hh:mm";

+0

Todo a la zona horaria no me causaba problemas. Era solo la parte de la zona horaria. Y estoy obteniendo datos de zona horaria, así que tuve que alterar un poco la entrada antes de analizar – AtomRiot

0

Estaba depurando exactamente el mismo problema. Tengo la misma cadena de fecha que usted que trabaja en 3.x y no 4.0. Mismos síntomas

Al mirar a través de la documentación NSDateFormatter veo:

La inicialización de un formateador Fecha - de inicio en el iPhone OS 2.0 a través de iPhone OS 3.2

Esto dice que el método init ya no se utiliza para iOS 4.0. No estoy seguro de lo que eso significa.

+0

. También vi eso al leer la referencia de clase, pero no hace otra mención de lo que significa. Y Xcode no lo marca como privado. – AtomRiot

0

El enlace que Elfred publicó hizo el truco. Me encontré con el mismo problema al convertir mi aplicación de 3.1.3 a iOS4. El enlace contiene la clase ISO8601DateFormatter, que es una extensión mucho más excelente que mi propia clase de utilidad de fecha.

Elfred wrote: I ran into this issue recently. I ended up using Peter Hosey's ISO8601 parser. It is available here: http://boredzo.org/iso8601unparser/

1

El formato que me dan es a medio camino entre RFC 822 y GMT. si cambio el "+00: 00" a "+0000", entonces puedo usar la "Z" en mi formato. y si lo cambio a "GMT + 00: 00" entonces puedo usar ZZZZ para obtener los datos correctamente. Parece que algo se ha eliminado para manejar este híbrido, ya que me funcionaba antes con OS 3.x.

0

Parece que NSDateFormatter se ha vuelto muy exigente.

-(void)dateFormatterTests { 
    NSDateFormatter *formatter; 

    formatter = [[NSDateFormatter alloc] init]; 

#ifdef WORKS 
    [formatter setDateFormat:@"yyyy-MM-dd"]; 
#elif defined(ALSO_WORKS) 
    [formatter setDateFormat:@"yyyy MM dd"]; 
    [formatter setLenient:YES]; 
#else // DOESN'T WORK 
    [formatter setDateFormat:@"yyyy MM dd"]; 
#endif 

    // Works per comments above 
    NSLog(@"dFS: %@", [formatter dateFromString:@"2010-01-13"]); 
    // Never works with any of the above formats 
    NSLog(@"dFS: %@", [formatter dateFromString:@"2010-01-13 22:00"]); 

    [formatter release]; formatter = nil; 
} 
+0

Este código no tiene en cuenta la zona horaria. Se me ha asignado la zona horaria en un formato específico y no puedo cambiar eso. – AtomRiot

+0

Lo siento. Ese punto de la publicación era mostrar que el formateador devolvería cero en los casos en los que crees que debería producir algo, como cuando decodifica solo una fecha, pero también agrega un tiempo en la cadena. Me alegra que lo hayas hecho funcionar. –

0

que tenían el mismo problema en mis aplicaciones, así Null Value from NSDateFormatter.

He encontrado mi problema a ser las siguientes:

me enviaba mi aplicación de una fecha y hora de esta manera: 07/16/2010 04:21:00 +00:00 con el formateador de esta manera: [dateFormatter setDateFormat:@"MM/dd/yyyy HH:mm:ss ZZZ"]

Parece que la parte ZZZ del formateo NO MÁS tiempo acepta el colon: en el tiempo.

Obras: 07/16/2010 04:21:00 +0000

no funciona: 07/16/2010 04:21:00 +00:00

para apoyar las aplicaciones actuales que están fuera, todo lo que hice fue buscar la parte +00:00 en la cadena y sustituirla por +0000.

Espero que esto ayude a los demás.

5

Este código se eliminarán los dos puntos extra, ya AtomRiot describe:

Converting it from:

  • NSString *stringDate = @"2010-06-21T20:06:36+00:00";

to:

  • NSString *stringDate = @"2010-06-21T20:06:36+0000";
// Remove colon in timezone as iOS 4+ NSDateFormatter breaks 
if (stringDate.length > 20) { 
    stringDate = [stringDate stringByReplacingOccurrencesOfString:@":" 
                 withString:@"" 
                  options:0 
                  range:NSMakeRange(20, stringDate.length-20)]; 
} 

para más detalles ver: https://devforums.apple.com/thread/45837

+0

Muchas gracias ... –

0

estoy usando tan simple como:

date_formatter = [[NSDateFormatter alloc] init]; 
     [date_formatter setDateStyle:NSDateFormatterShortStyle]; 
     [date_formatter setTimeStyle:NSDateFormatterNoStyle]; 

y esto está funcionando genial. No entiendo cómo pueden despreciar el método init, cuando la clase es una subclase de NSDateFormatter NSObject

2

Parece que la documentación de Apple es, así, 'complicado':

The format string uses the format patterns from the Unicode standard (this reference is to version tr35-6 for Mac OS X v10.5; for Mac OS X v10.4 use version tr35-4).

y

iOS: The v10.0 compatibility mode is not available on iOS—only the 10.4 mode is available.

de acuerdo a la versión tr35-4:

Use 1 for GMT format, 2 for RFC 822

Z{1} GMT-08:00
Z{2} -0800

Pero de acuerdo con la normaUnicode:

Use one to three letters for RFC 822, four letters for GMT format.

Z{1,3} -0800
Z{4} GMT-08:00

Así que parece que el IOS 4 está usando tr35-6 - el estándar Unicode, por lo que 00: 00 ahora falla contra la 'Z' .

me trataron -08: 00 contra 'ZZZZ' en mi NSDateFormatter y fallaron en IOS 4. GMT-08: 00, sin embargo, ha funcionado. Parece que ahora se requiere la zona horaria (GMT), en lugar de ser opcional, ya que puede haber sido en iOS 3.

Cuestiones relacionadas