¿Hay una forma sencilla de convertir una marca de tiempo ISO8601 a una fecha formateada?


Si utilizo el siguiente código:

NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];   
[dateFormatter setDateFormat:@"yyyy-MM-dd'T'HH:mm"];
NSDate *myDate = [dateFormatter dateFromString:@"2010-01-28T15:22:23.863"];
NSLog(@"%@", [dateFormatter stringFromDate:myDate]);

Se convierte con éxito a un objeto Date, sin embargo, parece que no puedo formatearlo de otra manera que yyyy-MM-dd'T'HH:mm, es decir, lo que se registra es 2010-01-28T15:22:23

Si cambio el formato de fecha para decir [dateFormatter setDateFormat:@"yyyy-MMMM-d'T'HH:mm"]; el objeto Date es null...

Así que mi pregunta final es cómo formatear una marca de tiempo ISO8601 de una base de datos SQL para usar, por ejemplo, NSDateFormatterMediumStyle para devolver "January 1, 2010"?

Author: rson, 2010-02-04

8 answers

Necesita otro formateador para manejar la salida. Pon esto después de tu código:

NSDateFormatter *anotherDateFormatter = [[NSDateFormatter alloc] init];   
[anotherDateFormatter setDateStyle:NSDateFormatterLongStyle];
[anotherDateFormatter setTimeStyle:NSDateFormatterShortStyle];
NSLog(@"%@", [anotherDateFormatter stringFromDate:myDate]);
 19
Author: osteven,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-02-04 17:46:03

Tengo un problema similar pero un poco más complejo, ¡y he encontrado una solución muy simple!

El problema: Mis fechas entrantes ISO8601 se ven así: 2006-06-14T11:06:00+02:00 Tienen un desplazamiento de zona horaria al final.

La solución: Utilice la ISO8601DateFormatter de Peter Hosey que puede descargar desde aquí.

ISO8601DateFormatter *formatter = [[ISO8601DateFormatter alloc] init];
NSDate *theDate = [formatter dateFromString:dateString];
[formatter release], formatter = nil;

Y

ISO8601DateFormatter *formatter = [[ISO8601DateFormatter alloc] init];
NSString *dateString = [formatter stringFromDate:[twitch dateTwitched]];
[formatter release], formatter = nil;
 42
Author: Matthew,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-07-08 10:57:42

Aquí está el código de ejemplo de apple

    NSDateFormatter * formatter = [[NSDateFormatter alloc] init];
    [formatter setDateFormat:@"yyyy'-'MM'-'dd'T'HH':'mm':'ss'Z'"];
    NSDate *date = [formatter dateFromString:dateString];

Enlace:https://developer.apple.com/library/ios/#qa/qa1480/_index.html

 19
Author: david,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-09-24 23:37:14

Solo por mencionar que desde iOS 6.0 puedes usar este formato:

 yyyy-MM-dd'T'HH:mm:ssZZZZZ
 12
Author: Marcin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-11-14 10:46:31

Tengo una implementación C muy rápida de analizar ISO8601 NSStrings a NSDates en SAMCategories. Puedes instalarlo con CocoaPods o simplemente copiar los archivos a tu proyecto.

He aquí cómo usarlo:

[NSDate sam_dateFromISO8601String:@"2013-08-24T06:51:21-07:00"]

Es muy robusto y soporta zonas horarias faltantes, etc. Como mi comentario anterior dijo, NSDateFormatter fue muy lento para mí al analizar muchas fechas. Cambiar a esta implementación ayudó mucho.

Este código se utiliza en 6 aplicaciones de producción (incluyendo Hipstamatic y Roon ) en las que he trabajado sin problemas conocidos. Hay un conjunto de pruebas para evitar la regresión.

En resumen, creo que esta es la mejor manera de analizar cadenas ISO8601 en Objective-C.


Un corto aparte, si usted está preocupado por el rendimiento y la transferencia, el envío de enteros en lugar de cadenas ISO8601 es muy preferido. Simplemente puede convertirlos en fechas con [NSDate dateWithTimeIntervalSince1970:yourInteger]. El rendimiento es tan rápido como usted puede hacerlo y hay menos caracteres para transferir a través del cable.

 6
Author: Sam Soffes,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 10:30:51

Debo tener en cuenta que la última vez que comprobé Apples NSDate los métodos no eran compatibles con ISO8601. Todavía tengo un error con Apple acerca de poner apoyo oficial en.

+ (id)dateWithNaturalLanguageString:(NSString *)string

Analizará correctamente (la última vez que lo ejecuté) y creará un objeto NSDate a partir de una cadena ISO801, aunque la documentación dice que no debe usarlo, ha funcionado en todas las fechas ISO8601 que he probado hasta ahora.

 5
Author: Colin Wheeler,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-04-04 14:49:37

@danielbeard respuesta funcionó para mí. Sin embargo, debe incluir la zona horaria, de lo contrario, convierte una fecha UTC en su zona horaria actual, que no es lo que desea.

- (NSDate *) dateFromISO8601DateString:(NSString *) dateString {
    NSDateFormatter * dateFormatter = [NSDateFormatter new];
    dateFormatter.timeZone = [NSTimeZone timeZoneWithName:@"UTC"];
    [dateFormatter setDateFormat:@"yyyy'-'MM'-'dd'T'HH':'mm':'ss'Z'"];
    NSDate * date = [dateFormatter dateFromString:dateString];
    return date;
}
 3
Author: gngrwzrd,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-07-08 16:15:57

@Capitán de hilo Pruebe este formato: "aaaa-MM-dd'T'HH: mm: ss.SSS "

 2
Author: Andi Utzinger,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-10-19 07:48:19