2010-05-09 17 views
7

¿Cómo analizo "2010-04-30T00: 45: 48.711127" en un NSDate? (y mantener toda la precisión)fecha Analizar ISO8601 en Objective-C (iPhone OS SDK)

+1

posible duplicado de [Analizar formatos de fecha no compatibles en medio de cacao ’ s NSDate] (http://stackoverflow.com/questions/399527/parsing-unsupported-date-formats-in-via-cocoas-nsdate) –

+1

pista FWIW: su pregunta es ambigua: no está 100% claro si está haciendo una pregunta "principiante" sobre Cocoa ("¿cómo? Analizo las fechas en un formato dado ") o avanzado. En su caso, en función de sus comentarios sobre las respuestas, usted estaba pidiendo la versión avanzada. Siendo así, es posible que reciba menos ruido en las respuestas si incluye una nota que diga: p. "Sé que NSDateFormatter se puede usar para este formato, pero se agota en tres lugares demasiado pronto". –

Respuesta

-1

Parece que NSDate solo tiene una precisión de milisegundos.

#import <Foundation/Foundation.h> 

int main (int argc, const char * argv[]) { 
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; 

    NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; 
    [dateFormatter setDateFormat:@"yyyy-MM-dd'T'hh:mm:ss.SSSSSS"]; 

    NSDate *date = [dateFormatter dateFromString:@"2010-04-30T00:45:48.711127"]; 

    NSLog(@"%@", date); 

    NSString *string = [dateFormatter stringFromDate:date]; 

    NSLog(@"%@", string); 

    [pool drain]; 
    return 0; 
} 

Ese código se obtiene la siguiente salida de la consola:

Program loaded. 
run 
[Switching to process 27202] 
Running… 
2010-05-08 20:02:46.342 TestNSDate[27202:a0f] 2010-04-30 00:45:48 -0700 
2010-05-08 20:02:46.344 TestNSDate[27202:a0f] 2010-04-30T12:45:48.711000 

Debugger stopped. 
Program exited with status value:0. 

Así "2010-04-30T00:45:48.711127" convirtiéndose en "2010-04-30T00:45:48.711000" no es probablemente lo que usted tiene en mente.

+0

Parece que ambos estamos atrapados en el mismo punto. Sin embargo, creo que el problema es con NSDateFormatter, ya que en muchos lugares está documentado que NSDate admite una precisión de microsegundos. –

+0

Hay NSTimeInterval que posee esa capacidad. Quizás un patrón compuesto esté en orden ... – WineSoaked

+0

Quizás debería ser más específico: ¿Qué tan importante es que almacene estas marcas de tiempo de resolución de menos de milisegundos (a falta de una mejor descripción) en NSDate mismo? ¿No podría una subclase que maneja la resolución de microsegundos hacer la diferencia para mantener la precisión adicional que necesita? – WineSoaked

4

Usted tiene su trabajo cortado para usted.

NSDate se deseche cualquier valores pasados ​​3 lugares decimales para los segundos. Se puede crear una subclase de NSDate de aferrarse a esa precisión, pero también tendrá que poner en práctica sus propios análisis y formateadores personalizados a la entrada y mostrarlo desde NSDateFormatter y CFDateFormatter, que se construye sobre, también se truncará precisión después de 3 decimales lugares. Dependiendo de lo que estés haciendo, eso no debería ser tan difícil.

Esta es una subclase simple (no se aplica NSCoding o NSCopying) que mantendrá toda la precisión que le dé.

@interface RMPreciseDate : NSDate { 
    double secondsFromAbsoluteTime; 
} 

@end 

@implementation RMPreciseDate 

- (NSTimeInterval)timeIntervalSinceReferenceDate { 
    return secondsFromAbsoluteTime; 
} 

- (id)initWithTimeIntervalSinceReferenceDate:(NSTimeInterval)secsToBeAdded { 
    if (!(self = [super init])) 
     return nil; 

    secondsFromAbsoluteTime = secsToBeAdded; 

    return self; 
} 

@end 

A continuación, puede pedir la -timeIntervalSince1970 obtener el Tiempo de tiempo UNIX.

Ya existe un ISO8601 date/time parser class, pero dado que está usando NSDateComponents para generar su fecha, actualmente está limitado a precisión de segundo completo, pero podría usarlo como punto de partida para crear representaciones más precisas.