Pregunta

Estoy intentando imprimir la fecha en un formato determinado:

NSDate *today = [[NSDate alloc] init];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:@"yyyyMMddHHmmss"];
NSString *dateStr = [dateFormatter stringFromDate:today];

Si el iPhone está configurado a 24 horas, esto funciona bien, si, por otra parte, el usuario lo ha configurado a 24 horas, luego vuelve a AM / PM (funciona bien hasta que alternes esta configuración) y luego agrega el AM / PM al final, aunque no lo pedí:

20080927030337 PM

¿Estoy haciendo algo mal o es un error con el firmware 2.1?

Edición 1: Descripción más clara

Editar 2 solución alternativa: resulta que esto es un error, para solucionarlo, establezco los caracteres de AM y PM en " " ;:

[dateFormatter setAMSymbol:@""];
[dateFormatter setPMSymbol:@""];
¿Fue útil?

Solución

Al usar el código que publicaste tanto en el simulador como en un teléfono con el firmware 2.1 y el horario de 24 horas en apagado, nunca tuve un AM / PM añadido a dateStr cuando lo hago:

NSLog(@"%@", dateStr);

¿Estás haciendo algo más con dateStr que no hayas publicado aquí? ¿Cómo estás comprobando el valor?

Seguimiento

  

Intente activar y desactivar la configuración de am / pm. Yo tampoco tuve el problema, hasta que hice eso. Lo estoy imprimiendo de la misma manera que tú.

Está bien, lo veo cuando hago esto también. Tiene que ser un error. Le recomiendo que presente un informe de error y solo busque y filtre los caracteres no deseados mientras tanto.

Otros consejos

El motivo de este comportamiento es la configuración regional, establece la configuración regional correcta.

Establezca el local de su NSDateFormatter en en_US_POSIX para solucionar este problema. Funciona tanto para el formato de 24 horas como para el de 12 horas.

En el sistema operativo del iPhone, el usuario puede anular la configuración predeterminada de hora de AM / PM en lugar de las 24 horas (a través de Configuración > General > Fecha y hora > Hora de 24 horas), lo que hace que NSDateFormatter se reescriba la cadena de formato que estableció. De apple doc

Prueba esto,

NSDate *today = [[NSDate alloc] init];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setLocale:[[NSLocale alloc] initWithLocaleIdentifier:@"en_US_POSIX"]];
[dateFormatter setDateFormat:@"yyyyMMddHHmmss"];
NSString *dateStr = [dateFormatter stringFromDate:today];

Aquí está la explicación del error del SDK de iPhone (también existe en 3.1 SDK beta)

  

Primero, un poco de historia en la interfaz de usuario del iPhone. Cuando iphone   los usuarios cambian el formato de su región entre, digamos, “Estados Unidos” y   "Francia", el ajuste de "Hora de 24 horas" de los usuarios se cambia automáticamente   al modo que prevalece en esa región. En francia, que   establecería el tiempo de 24 horas en "ON", y en los EE. UU., lo establecería en   "APAGADO". Los usuarios pueden entonces anular manualmente esa configuración y eso es   donde comienza el problema.

     

El problema proviene de NSDateFormatter de alguna manera "atascarse" en el   Modo de 12 o 24 horas que el usuario ha seleccionado manualmente. Así que si un   El usuario francés selecciona manualmente el modo de 12 horas y la aplicación   solicitó a NSDateFormatter el tiempo de salida con el formato de 24 horas   "HHmm", en realidad recibiría tiempo en un formato de 12 horas, por ejemplo.   "01:00 PM", como si la aplicación hubiera solicitado "hhmm aa".   Lo contrario sucedería si un usuario estadounidense seleccionara manualmente el modo de 24 horas:   el tiempo de salida con el formato de 12 horas "hhmm aa" en realidad obtendría   la hora en el formato de 24 horas, por ejemplo, “17:00 ?.

Se pueden encontrar más detalles y una posible solución en este blog .

Establecer la configuración regional en el formateador de fecha en en_US soluciona el problema para mí:

    NSDateFormatter * f = [[NSDateFormatter alloc] init];
    [f setDateFormat:@"yyyy-MM-dd'T'HH:mm:ss'Z'"];
    f.timeZone = [NSTimeZone timeZoneForSecondsFromGMT:0];
    f.calendar = [[[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar] autorelease];
    f.locale = [[[NSLocale alloc] initWithLocaleIdentifier:@"en_US"] autorelease];

No estoy seguro de si también es necesario agregar el calendario, pero esto funciona bien.

Creo que esta es la solución.

NSDateFormatter *df =[[NSDateFormatter alloc] init];
        [df setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
        NSLocale *usLocale = [[NSLocale alloc] initWithLocaleIdentifier:@"en_US"];

[df setLocale: usLocale];

[usLocale release];

 NSDate *documento_en_Linea =[[[NSDate alloc] init]autorelease];

documento_en_Linea=[df dateFromString:@"2010-07-16 21:40:33"];

[df release];

        NSLog(@"fdocumentoenLineaUTC:%@!",documento_en_Linea);


//ouput  
     fdocumentoenLineaUTC:2010-07-16 09:40:33 p.m. -0500!

Para aquellos que encuentren esta pregunta que quieren usar NSDateFormatter para analizar las 24 horas y están atacando este error, utilizan NSDateComponents para analizar fechas y horas que tienen un formato conocido evitan este problema:

NSString *dateStr = @"2010-07-05";
NSString *timeStr = @"13:30";

NSDateComponents *components = [[NSDateComponents alloc] init];
components.year = [[dateStr substringToIndex:4] intValue];
components.month = [[dateStr substringWithRange:NSMakeRange(5, 2)] intValue];
components.day = [[dateStr substringFromIndex:8] intValue];
components.hour = [[timeStr substringToIndex:2] intValue];
components.minute = [[timeStr substringFromIndex:3] intValue];

NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];

NSDate *date = [calendar dateFromComponents:components];

[components release];
[calendar release];

Esto también debería funcionar (aunque estoy viendo algunos resultados bizzare).

-(NSString*)lowLevTime:(NSString*)stringFormat {
    char buffer[50];
    const char *format = [stringFormat UTF8String];
    time_t rawtime;
    struct tm * timeinfo;
    time(&rawtime);
    timeinfo = localtime(&rawtime);
    strftime(buffer, sizeof(buffer), format, timeinfo);
    return [NSString  stringWithCString:buffer encoding:NSASCIIStringEncoding];
}

Respuesta corta: intente [dateFormatter setDateFormat: @ " yyyyMMddhhmmss "]; para el formato de 12 horas (observe el hh en minúscula).

Ha sido un tema frustrante porque muchos sitios web indican usar HH durante horas (incluida la documentación oficial de Apple), pero eso lo configura en formato de 24 horas, mientras que hh Usa formato de 12 horas. Consulte http://unicode.org/reports/tr35/tr35-6.html# Date_Format_Patterns para más detalles.

Como bono adicional, tenga en cuenta que también puede usar KK o kk para el formato de hora del día, que probablemente estará desactivado en uno.

Actualización: Recientemente estuve viendo NSLocale (https://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/NSLocale_Class/Reference/Reference.html) y parece que puedes usar autoupdatingCurrentLocale to aplicar los cambios realizados desde dentro de la aplicación a la configuración regional. El resultado de esto es que incluso si el teléfono está configurado para usar un reloj de 24 horas (como cuando cambió a Francia), puede hacer un cambio de 12/24 para la aplicación que no afectará a ninguna otra aplicación en el teléfono, o solicitarle que deje la aplicación para realizar el cambio.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top