Question

J'essaie d'imprimer la date dans un certain format:

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

Si l'iPhone est réglé sur l'heure 24 heures, cela fonctionne bien, mais si l'utilisateur l'a réglé sur l'heure 24 heures, puis de nouveau sur AM / PM (cela fonctionne bien jusqu'à ce que vous basculiez ce paramètre), puis ajoute à la fin AM / PM même si je ne l’avais pas demandé:

20080927030337 PM

Est-ce que je fais quelque chose de mal ou est-ce un bogue avec le firmware 2.1?

Modifier 1: description plus claire

Solution de contournement 2: il s’avère qu’il s’agit d’un bogue. Pour le résoudre, je règle les caractères AM et PM sur "":

.
[dateFormatter setAMSymbol:@""];
[dateFormatter setPMSymbol:@""];
Était-ce utile?

La solution

À l'aide du code que vous avez fourni à la fois sur le simulateur et sur un téléphone avec le micrologiciel 2.1 et l'heure désactivée, l'heure de début et l'après-midi n'a jamais été ajoutée à dateStr lorsque je le fais:

NSLog(@"%@", dateStr);

Faites-vous autre chose avec dateStr que vous n’avez pas posté ici? Comment vérifiez-vous la valeur?

Suivi

  

Essayez d’activer puis de désactiver le réglage am / pm. Je n'ai pas eu le problème non plus, jusqu'à ce que je l'aie fait. Je l’imprime de la même manière que vous.

D'accord, je le vois quand je fais ça aussi. Ça doit être un bug. Je vous recommande de rédiger un rapport de bogue et de rechercher et filtrer les caractères non désirés entre-temps.

Autres conseils

La raison de ce problème est Locale. Elle définit le paramètre régional correct.

Définissez l'emplacement de votre NSDateFormatter sur en_US_POSIX pour résoudre ce problème. Il fonctionne pour les formats 24 heures et 12 heures.

Sur l'iPhone OS, l'utilisateur peut remplacer le paramètre par défaut AM / PM par rapport à l'heure (via Paramètres> Général> Date & heure> 24 heures), ce qui provoque la réécriture de NSDateFormatter. la chaîne de format que vous définissez. De document Apple

Essayez ceci,

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];

Voici l'explication du bogue du SDK de l'iPhone (également présent dans la version 3.1 beta du SDK)

  

Tout d'abord, un peu de contexte sur l'interface utilisateur de l'iPhone. Quand l'iPhone   Les utilisateurs changent le format de leur région entre, par exemple, & # 8220; États-Unis & # 8221; et   & # 8220; France & # 8221; les utilisateurs & # 8217; & # 8220; Heure sur 24 & # 8221; le réglage est automatiquement commuté   au mode qui prévaut le plus dans cette région. En France, ça   définirait l'heure sur 24 heures sur & # 8220; ON & # 8221; et aux États-Unis, cela le réglerait sur   & # 8220; OFF & # 8221 ;. Les utilisateurs peuvent ensuite remplacer manuellement ce paramètre et ce & s   où les ennuis commencent.

     

Le problème vient de NSDateFormatter d’une façon ou d’une autre & # 8220; rester bloqué & # 8221; dans le   Mode horaire 12 ou 24 heures sélectionné manuellement par l'utilisateur. Donc si un   L’utilisateur français sélectionne manuellement le mode 12 heures et l’application   NSDateFormatter a demandé de fournir l'heure au format 24 heures   & # 8220; HHmm & # 8221 ;, il recevrait en fait l'heure au format 12 heures, par exemple.   & # 8220; 13: 00 & # 8221 ;, comme si l'application avait demandé à la place & # 8220; hhmm aa & # 8221 ;.   L'inverse se produirait si un utilisateur américain sélectionnait manuellement le mode 24 heures:   afficher l'heure au format 12 heures & # 8220; hhmm aa & # 8221; serait effectivement obtenir   vous utilisez plutôt le format 24 heures, par exemple & # 8220; 17: 00 & # 8243;.

Vous trouverez plus de détails et une solution de contournement à ce sujet blog .

La définition du paramètre régional du formateur de date sur en_US résout le problème pour moi:

    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];

Je ne sais pas si l'ajout du calendrier est également nécessaire, mais cela fonctionne bien.

Je pense que c'est la solution.

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!

Pour ceux qui trouvent cette question et qui souhaitent utiliser NSDateFormatter pour analyser une heure de 24 heures et qui rencontrent ce bogue, utilisent NSDateComponents pour analyser les dates et les heures dont le format connu est à côté de ce problème:

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];

Cela devrait également fonctionner (je constate cependant quelques résultats miracles).

-(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];
}

Réponse courte: essayez [dateFormatter setDateFormat: @ "yyyyMMddhhmmss"]] pour le format de 12 heures (notez le hh en minuscule).

C’est un sujet frustrant, car de nombreux sites Web recommandent d’utiliser HH pendant des heures (y compris la documentation officielle Apple), mais cela le définit au format 24 heures, alors que hh utilise le format 12 heures. Voir http://unicode.org/reports/tr35/tr35-6.html# Date_Format_Patterns pour plus de détails.

En prime, notez que vous pouvez également utiliser KK ou kk pour le format de l'heure du jour, qui sera probablement décalé de un.

Mise à jour: Je regardais récemment NSLocale (https://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/NSLocale_Class/Reference/Reference.html) et il semblerait que vous puissiez utiliser AutoupdatingCurrentLocale appliquer les modifications apportées depuis l'application à l'environnement local. Le résultat de ceci est que même si le téléphone est configuré pour utiliser une horloge de 24 heures (comme lorsque vous êtes passé en France), vous pouvez créer une bascule 12/24 pour l'application qui n'aura aucune incidence sur les autres applications du téléphone, ou vous obliger à quitter l'application pour effectuer le changement.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top